Merge branch 'master' into astron-master
This commit is contained in:
commit
6acec4932e
|
|
@ -1,9 +1,52 @@
|
|||
# makepanda directories
|
||||
/built*/
|
||||
/thirdparty/
|
||||
/targetroot/
|
||||
/dstroot/
|
||||
|
||||
# Core dumps
|
||||
core
|
||||
core.*
|
||||
vgcore.*
|
||||
|
||||
# Editor files/directories
|
||||
*.save
|
||||
*.save.1
|
||||
*.sublime-workspace
|
||||
.vscode/
|
||||
|
||||
# Temporary build files
|
||||
/_vfsimporter.*
|
||||
*.pdb
|
||||
*.obj
|
||||
*.o
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Produced installer/executables
|
||||
/*.exe
|
||||
/*.deb
|
||||
/*.rpm
|
||||
/*.app
|
||||
/*.pkg
|
||||
/*.dmg
|
||||
/*.whl
|
||||
|
||||
# CMake
|
||||
/build/
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
CMakeScripts/
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
CTestTestfile.cmake
|
||||
|
||||
# Windows
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Python
|
||||
__pycache__
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ sudo: false
|
|||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
env: PYTHONV=python2.7 FLAGS=
|
||||
env: PYTHONV=python2.7 FLAGS=--optimize=4
|
||||
- compiler: clang
|
||||
env: PYTHONV=python3 FLAGS=--installer
|
||||
- compiler: clang
|
||||
|
|
|
|||
|
|
@ -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?-*
|
||||
|
|
@ -11,10 +11,6 @@
|
|||
* @date 2009-09-08
|
||||
*/
|
||||
|
||||
#pragma warning (disable:4996)
|
||||
#pragma warning (disable:4005)
|
||||
#pragma warning(disable:4275)
|
||||
|
||||
#ifndef _AIBEHAVIORS_H
|
||||
#define _AIBEHAVIORS_H
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,6 @@
|
|||
* @date 2009-09-08
|
||||
*/
|
||||
|
||||
#pragma warning (disable:4996)
|
||||
#pragma warning (disable:4005)
|
||||
#pragma warning(disable:4275)
|
||||
|
||||
|
||||
#ifndef _AICHARACTER_H
|
||||
#define _AICHARACTER_H
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,6 @@
|
|||
* @date 2009-09-08
|
||||
*/
|
||||
|
||||
#pragma warning (disable:4996)
|
||||
#pragma warning (disable:4005)
|
||||
#pragma warning(disable:4275)
|
||||
|
||||
#ifndef _AI_GLOBALS_H
|
||||
#define _AI_GLOBALS_H
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,6 @@
|
|||
* @date 2009-09-08
|
||||
*/
|
||||
|
||||
#pragma warning (disable:4996)
|
||||
#pragma warning (disable:4005)
|
||||
#pragma warning(disable:4275)
|
||||
|
||||
|
||||
#ifndef _AIWORLD_H
|
||||
#define _AIWORLD_H
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ obstacle_detection() {
|
|||
CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
|
||||
LVecBase3 avoidance(0.0, 0.0, 0.0);
|
||||
double distance = 0x7fff ;
|
||||
double expanded_radius;
|
||||
double expanded_radius = 0;
|
||||
LVecBase3 to_obstacle;
|
||||
LVecBase3 prev_avoidance;
|
||||
for(unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) {
|
||||
|
|
@ -89,8 +89,8 @@ do_obstacle_avoidance() {
|
|||
CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();
|
||||
PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
|
||||
CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
|
||||
double distance_needed = offset.length() - bsphere->get_radius() - np_sphere->get_radius();
|
||||
if((obstacle_detection())) {
|
||||
|
||||
if (obstacle_detection()) {
|
||||
LVecBase3 direction = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
|
||||
direction.normalize();
|
||||
float forward_component = offset.dot(direction);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
* parameter type accepts an arbitrary (or possibly fixed) number of nested
|
||||
* fields, all of which are of the same type.
|
||||
*/
|
||||
class EXPCL_DIRECT DCArrayParameter : public DCParameter {
|
||||
class DCArrayParameter : public DCParameter {
|
||||
public:
|
||||
DCArrayParameter(DCParameter *element_type,
|
||||
const DCUnsignedIntRange &size = DCUnsignedIntRange());
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
* This defines an interface to the Distributed Class, and is always
|
||||
* implemented as a remote procedure method.
|
||||
*/
|
||||
class EXPCL_DIRECT DCAtomicField : public DCField {
|
||||
class DCAtomicField : public DCField {
|
||||
public:
|
||||
DCAtomicField(const string &name, DCClass *dclass, bool bogus_field);
|
||||
virtual ~DCAtomicField();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class DCParameter;
|
|||
/**
|
||||
* Defines a particular DistributedClass as read from an input .dc file.
|
||||
*/
|
||||
class EXPCL_DIRECT DCClass : public DCDeclaration {
|
||||
class DCClass : public DCDeclaration {
|
||||
public:
|
||||
DCClass(DCFile *dc_file, const string &name,
|
||||
bool is_struct, bool bogus_class);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class DCClass;
|
|||
* This represents a class (or struct) object used as a parameter itself.
|
||||
* This means that all the fields of the class get packed into the message.
|
||||
*/
|
||||
class EXPCL_DIRECT DCClassParameter : public DCParameter {
|
||||
class DCClassParameter : public DCParameter {
|
||||
public:
|
||||
DCClassParameter(const DCClass *dclass);
|
||||
DCClassParameter(const DCClassParameter ©);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class DCSwitch;
|
|||
* only purpose is so that classes and typedefs can be stored in one list
|
||||
* together so they can be ordered correctly on output.
|
||||
*/
|
||||
class EXPCL_DIRECT DCDeclaration {
|
||||
class DCDeclaration {
|
||||
public:
|
||||
virtual ~DCDeclaration();
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class HashGenerator;
|
|||
/**
|
||||
* A single field of a Distributed Class, either atomic or molecular.
|
||||
*/
|
||||
class EXPCL_DIRECT DCField : public DCPackerInterface, public DCKeywordList {
|
||||
class DCField : public DCPackerInterface, public DCKeywordList {
|
||||
public:
|
||||
DCField();
|
||||
DCField(const string &name, DCClass *dclass);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class DCDeclaration;
|
|||
* Represents the complete list of Distributed Class descriptions as read from
|
||||
* a .dc file.
|
||||
*/
|
||||
class EXPCL_DIRECT DCFile {
|
||||
class DCFile {
|
||||
PUBLISHED:
|
||||
DCFile();
|
||||
~DCFile();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class HashGenerator;
|
|||
* define a communication property associated with a field, for instance
|
||||
* "broadcast" or "airecv".
|
||||
*/
|
||||
class EXPCL_DIRECT DCKeyword : public DCDeclaration {
|
||||
class DCKeyword : public DCDeclaration {
|
||||
public:
|
||||
DCKeyword(const string &name, int historical_flag = ~0);
|
||||
virtual ~DCKeyword();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class HashGenerator;
|
|||
* This is a list of keywords (see DCKeyword) that may be set on a particular
|
||||
* field.
|
||||
*/
|
||||
class EXPCL_DIRECT DCKeywordList {
|
||||
class DCKeywordList {
|
||||
public:
|
||||
DCKeywordList();
|
||||
DCKeywordList(const DCKeywordList ©);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class DCParameter;
|
|||
* This represents a combination of two or more related atomic fields, that
|
||||
* will often be treated as a unit.
|
||||
*/
|
||||
class EXPCL_DIRECT DCMolecularField : public DCField {
|
||||
class DCMolecularField : public DCField {
|
||||
public:
|
||||
DCMolecularField(const string &name, DCClass *dclass);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
/**
|
||||
* This is a block of data that receives the results of DCPacker.
|
||||
*/
|
||||
class EXPCL_DIRECT DCPackData {
|
||||
class DCPackData {
|
||||
PUBLISHED:
|
||||
INLINE DCPackData();
|
||||
INLINE ~DCPackData();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class DCSwitchParameter;
|
|||
* See also direct/src/doc/dcPacker.txt for a more complete description and
|
||||
* examples of using this class.
|
||||
*/
|
||||
class EXPCL_DIRECT DCPacker {
|
||||
class DCPacker {
|
||||
PUBLISHED:
|
||||
DCPacker();
|
||||
~DCPacker();
|
||||
|
|
@ -216,7 +216,7 @@ private:
|
|||
const DCPackerCatalog *_catalog;
|
||||
const DCPackerCatalog::LiveCatalog *_live_catalog;
|
||||
|
||||
class EXPCL_DIRECT StackElement {
|
||||
class StackElement {
|
||||
public:
|
||||
// As an optimization, we implement operator new and delete here to
|
||||
// minimize allocation overhead during push() and pop().
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class DCSwitchParameter;
|
|||
* requested from a particular field; its ownership is retained by the field
|
||||
* so it must not be deleted.
|
||||
*/
|
||||
class EXPCL_DIRECT DCPackerCatalog {
|
||||
class DCPackerCatalog {
|
||||
private:
|
||||
DCPackerCatalog(const DCPackerInterface *root);
|
||||
DCPackerCatalog(const DCPackerCatalog ©);
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ END_PUBLISH
|
|||
* Normally these methods are called only by the DCPacker object; the user
|
||||
* wouldn't normally call these directly.
|
||||
*/
|
||||
class EXPCL_DIRECT DCPackerInterface {
|
||||
class DCPackerInterface {
|
||||
public:
|
||||
DCPackerInterface(const string &name = string());
|
||||
DCPackerInterface(const DCPackerInterface ©);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class HashGenerator;
|
|||
* This may also be a typedef reference to another type, which has the same
|
||||
* properties as the referenced type, but a different name.
|
||||
*/
|
||||
class EXPCL_DIRECT DCParameter : public DCField {
|
||||
class DCParameter : public DCField {
|
||||
protected:
|
||||
DCParameter();
|
||||
DCParameter(const DCParameter ©);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
* divisor, which is meaningful only for the numeric type elements (and
|
||||
* represents a fixed-point numeric convention).
|
||||
*/
|
||||
class EXPCL_DIRECT DCSimpleParameter : public DCParameter {
|
||||
class DCSimpleParameter : public DCParameter {
|
||||
public:
|
||||
DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
|
||||
DCSimpleParameter(const DCSimpleParameter ©);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class DCField;
|
|||
* and represents two or more alternative unpacking schemes based on the first
|
||||
* field read.
|
||||
*/
|
||||
class EXPCL_DIRECT DCSwitch : public DCDeclaration {
|
||||
class DCSwitch : public DCDeclaration {
|
||||
public:
|
||||
DCSwitch(const string &name, DCField *key_parameter);
|
||||
virtual ~DCSwitch();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class DCSwitch;
|
|||
* This represents a switch object used as a parameter itself, which packs the
|
||||
* appropriate fields of the switch into the message.
|
||||
*/
|
||||
class EXPCL_DIRECT DCSwitchParameter : public DCParameter {
|
||||
class DCSwitchParameter : public DCParameter {
|
||||
public:
|
||||
DCSwitchParameter(const DCSwitch *dswitch);
|
||||
DCSwitchParameter(const DCSwitchParameter ©);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class DCParameter;
|
|||
* This represents a single typedef declaration in the dc file. It assigns a
|
||||
* particular type to a new name, just like a C typedef.
|
||||
*/
|
||||
class EXPCL_DIRECT DCTypedef : public DCDeclaration {
|
||||
class DCTypedef : public DCDeclaration {
|
||||
public:
|
||||
DCTypedef(DCParameter *parameter, bool implicit = false);
|
||||
DCTypedef(const string &name);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -402,8 +402,28 @@ send_datagram(const Datagram &dg) {
|
|||
}
|
||||
|
||||
#ifdef WANT_NATIVE_NET
|
||||
if(_native)
|
||||
return _bdc.SendMessage(dg);
|
||||
if (_native) {
|
||||
bool result = _bdc.SendMessage(dg);
|
||||
if (!result && _bdc.IsConnected()) {
|
||||
#ifdef HAVE_PYTHON
|
||||
ostringstream s;
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03030000
|
||||
PyObject *exc_type = PyExc_ConnectionError;
|
||||
#else
|
||||
PyObject *exc_type = PyExc_OSError;
|
||||
#endif
|
||||
|
||||
s << endl << "Error sending message: " << endl;
|
||||
dg.dump_hex(s);
|
||||
s << "Message data: " << dg.get_data() << endl;
|
||||
|
||||
string message = s.str();
|
||||
PyErr_SetString(exc_type, message.c_str());
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NET
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -33,7 +33,7 @@ class FileSpec:
|
|||
if st is None:
|
||||
st = os.stat(pathname.toOsSpecific())
|
||||
self.size = st.st_size
|
||||
self.timestamp = st.st_mtime
|
||||
self.timestamp = int(st.st_mtime)
|
||||
|
||||
self.readHash(pathname)
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ class FileSpec:
|
|||
self.__correctHash(packageDir, pathname, st, notify)
|
||||
return False
|
||||
|
||||
if st.st_mtime == self.timestamp:
|
||||
if int(st.st_mtime) == self.timestamp:
|
||||
# If the size is right and the timestamp is right, the
|
||||
# file passes.
|
||||
if notify:
|
||||
|
|
@ -198,7 +198,7 @@ class FileSpec:
|
|||
# The hash is OK. If the timestamp is wrong, change it back
|
||||
# to what we expect it to be, so we can quick-verify it
|
||||
# successfully next time.
|
||||
if st.st_mtime != self.timestamp:
|
||||
if int(st.st_mtime) != self.timestamp:
|
||||
self.__updateTimestamp(pathname, st)
|
||||
|
||||
return True
|
||||
|
|
@ -219,7 +219,7 @@ class FileSpec:
|
|||
if notify:
|
||||
notify.info("Correcting timestamp of %s to %d (%s)" % (
|
||||
self.filename, st.st_mtime, time.asctime(time.localtime(st.st_mtime))))
|
||||
self.timestamp = st.st_mtime
|
||||
self.timestamp = int(st.st_mtime)
|
||||
|
||||
def checkHash(self, packageDir, pathname, st):
|
||||
""" Returns true if the file has the expected md5 hash, false
|
||||
|
|
|
|||
|
|
@ -1848,7 +1848,7 @@ class Packager:
|
|||
|
||||
def addEggFile(self, file):
|
||||
# Precompile egg files to bam's.
|
||||
np = self.packager.loader.loadModel(file.filename)
|
||||
np = self.packager.loader.loadModel(file.filename, self.packager.loaderOptions)
|
||||
if not np:
|
||||
raise Exception('Could not read egg file %s' % (file.filename))
|
||||
|
||||
|
|
@ -1862,6 +1862,8 @@ class Packager:
|
|||
if not bamFile.openRead(file.filename):
|
||||
raise Exception('Could not read bam file %s' % (file.filename))
|
||||
|
||||
bamFile.getReader().setLoaderOptions(self.packager.loaderOptions)
|
||||
|
||||
if not bamFile.resolve():
|
||||
raise Exception('Could not resolve bam file %s' % (file.filename))
|
||||
|
||||
|
|
@ -2492,6 +2494,14 @@ class Packager:
|
|||
self.sfxManagerList = None
|
||||
self.musicManager = None
|
||||
|
||||
# These options will be used when loading models and textures. By
|
||||
# default we don't load textures beyond the header and don't store
|
||||
# models in the RAM cache in order to conserve on memory usage.
|
||||
opts = LoaderOptions()
|
||||
opts.setFlags(opts.getFlags() | LoaderOptions.LFNoRamCache)
|
||||
opts.setTextureFlags(opts.getTextureFlags() & ~LoaderOptions.TFPreload)
|
||||
self.loaderOptions = opts
|
||||
|
||||
# This is filled in during readPackageDef().
|
||||
self.packageList = []
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ class panda3d(package):
|
|||
'direct.stdpy.*',
|
||||
'direct.task.*')
|
||||
|
||||
# Keep these modules for backward compatibility.
|
||||
module('pandac.PandaModules', 'pandac.extension_native_helpers')
|
||||
|
||||
module('panda3d.core',
|
||||
'panda3d.direct',
|
||||
'panda3d.fx',
|
||||
|
|
@ -462,6 +465,8 @@ class packp3d(p3d):
|
|||
|
||||
mainModule('direct.p3d.packp3d')
|
||||
|
||||
file('packp3d.prc', extract = True, text = "preload-textures false")
|
||||
|
||||
|
||||
class ppackage(p3d):
|
||||
# As above, a packaging utility. This is the fully-general ppackage
|
||||
|
|
@ -475,6 +480,8 @@ class ppackage(p3d):
|
|||
|
||||
mainModule('direct.p3d.ppackage')
|
||||
|
||||
file('ppackage.prc', extract = True, text = "preload-textures false")
|
||||
|
||||
|
||||
class ppatcher(p3d):
|
||||
# A handy utility to go along with ppackage. This builds
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
/p3d_plugin_config.h
|
||||
|
|
@ -21,8 +21,6 @@
|
|||
#include "get_tinyxml.h"
|
||||
#include "windowHandle.h"
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
class P3DSession;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1421,6 +1421,17 @@ create_runtime_environment() {
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
// If we're running from the console, make sure that terminating the parent
|
||||
// process will cause the child process to terminate as well.
|
||||
if (_console_environment) {
|
||||
struct sigaction ignore;
|
||||
memset(&ignore, 0, sizeof(ignore));
|
||||
ignore.sa_handler = SIG_IGN;
|
||||
sigaction(SIGINT, &ignore, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
_created_runtime_environment = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
/P3DActiveX.rc
|
||||
|
|
@ -1 +0,0 @@
|
|||
/nppanda3d.rc
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/p3d_plugin_config.h
|
||||
/panda3d.rc
|
||||
|
|
@ -278,6 +278,15 @@ class BufferViewer(DirectObject):
|
|||
self.analyzeTextureSet(self.exclude, exclude)
|
||||
self.analyzeTextureSet(self.include, include)
|
||||
|
||||
# Use a custom sampler when applying the textures. This fixes
|
||||
# wrap issues and prevents depth compare on shadow maps.
|
||||
sampler = SamplerState()
|
||||
sampler.setWrapU(SamplerState.WM_clamp)
|
||||
sampler.setWrapV(SamplerState.WM_clamp)
|
||||
sampler.setWrapW(SamplerState.WM_clamp)
|
||||
sampler.setMinfilter(SamplerState.FT_linear)
|
||||
sampler.setMagfilter(SamplerState.FT_nearest)
|
||||
|
||||
# Generate a list of cards and the corresponding windows.
|
||||
cards = []
|
||||
wins = []
|
||||
|
|
@ -290,7 +299,7 @@ class BufferViewer(DirectObject):
|
|||
for face in range(6):
|
||||
self.cardmaker.setUvRangeCube(face)
|
||||
card = NodePath(self.cardmaker.generate())
|
||||
card.setTexture(tex)
|
||||
card.setTexture(tex, sampler)
|
||||
cards.append(card)
|
||||
elif (tex.getTextureType() == Texture.TT2dTextureArray):
|
||||
for layer in range(tex.getZSize()):
|
||||
|
|
@ -301,11 +310,11 @@ class BufferViewer(DirectObject):
|
|||
# the fixed-function pipeline, so we need to
|
||||
# enable the shader generator to view them.
|
||||
card.setShaderAuto()
|
||||
card.setTexture(tex)
|
||||
card.setTexture(tex, sampler)
|
||||
cards.append(card)
|
||||
else:
|
||||
card = win.getTextureCard()
|
||||
card.setTexture(tex)
|
||||
card.setTexture(tex, sampler)
|
||||
cards.append(card)
|
||||
wins.append(win)
|
||||
exclude[tex] = 1
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class Loader(DirectObject):
|
|||
self.extraArgs = extraArgs
|
||||
self.numRemaining = numObjects
|
||||
self.cancelled = False
|
||||
self.requests = {}
|
||||
self.requests = set()
|
||||
|
||||
def gotObject(self, index, object):
|
||||
self.objects[index] = object
|
||||
|
|
@ -45,6 +45,8 @@ class Loader(DirectObject):
|
|||
self.base = base
|
||||
self.loader = PandaLoader.getGlobalPtr()
|
||||
|
||||
self.__requests = {}
|
||||
|
||||
self.hook = "async_loader_%s" % (Loader.loaderIndex)
|
||||
Loader.loaderIndex += 1
|
||||
self.accept(self.hook, self.__gotAsyncObject)
|
||||
|
|
@ -116,7 +118,7 @@ class Loader(DirectObject):
|
|||
"""
|
||||
|
||||
assert Loader.notify.debug("Loading model: %s" % (modelPath))
|
||||
if loaderOptions == None:
|
||||
if loaderOptions is None:
|
||||
loaderOptions = LoaderOptions()
|
||||
else:
|
||||
loaderOptions = LoaderOptions(loaderOptions)
|
||||
|
|
@ -156,7 +158,7 @@ class Loader(DirectObject):
|
|||
result = []
|
||||
for modelPath in modelList:
|
||||
node = self.loader.loadSync(Filename(modelPath), loaderOptions)
|
||||
if (node != None):
|
||||
if node is not None:
|
||||
nodePath = NodePath(node)
|
||||
else:
|
||||
nodePath = None
|
||||
|
|
@ -179,16 +181,16 @@ class Loader(DirectObject):
|
|||
# callback (passing it the models on the parameter list).
|
||||
|
||||
cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
|
||||
i=0
|
||||
i = 0
|
||||
for modelPath in modelList:
|
||||
request = self.loader.makeAsyncRequest(Filename(modelPath), loaderOptions)
|
||||
if priority is not None:
|
||||
request.setPriority(priority)
|
||||
request.setDoneEvent(self.hook)
|
||||
request.setPythonObject((cb, i))
|
||||
i+=1
|
||||
self.loader.loadAsync(request)
|
||||
cb.requests[request] = True
|
||||
cb.requests.add(request)
|
||||
self.__requests[request] = (cb, i)
|
||||
i += 1
|
||||
return cb
|
||||
|
||||
def cancelRequest(self, cb):
|
||||
|
|
@ -200,6 +202,7 @@ class Loader(DirectObject):
|
|||
cb.cancelled = True
|
||||
for request in cb.requests:
|
||||
self.loader.remove(request)
|
||||
del self.__requests[request]
|
||||
cb.requests = None
|
||||
|
||||
def isRequestPending(self, cb):
|
||||
|
|
@ -273,7 +276,7 @@ class Loader(DirectObject):
|
|||
# to resolve it for us.
|
||||
options = LoaderOptions(LoaderOptions.LFSearch | LoaderOptions.LFNoDiskCache | LoaderOptions.LFCacheOnly)
|
||||
modelNode = self.loader.loadSync(Filename(model), options)
|
||||
if modelNode == None:
|
||||
if modelNode is None:
|
||||
# Model not found.
|
||||
assert Loader.notify.debug("Unloading model not loaded: %s" % (model))
|
||||
return
|
||||
|
|
@ -293,7 +296,7 @@ class Loader(DirectObject):
|
|||
a callback is used, the model is saved asynchronously, and the
|
||||
true/false status is passed to the callback function. """
|
||||
|
||||
if loaderOptions == None:
|
||||
if loaderOptions is None:
|
||||
loaderOptions = LoaderOptions()
|
||||
else:
|
||||
loaderOptions = LoaderOptions(loaderOptions)
|
||||
|
|
@ -342,16 +345,16 @@ class Loader(DirectObject):
|
|||
# callback (passing it the models on the parameter list).
|
||||
|
||||
cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
|
||||
i=0
|
||||
i = 0
|
||||
for modelPath, node in modelList:
|
||||
request = self.loader.makeAsyncSaveRequest(Filename(modelPath), loaderOptions, node)
|
||||
if priority is not None:
|
||||
request.setPriority(priority)
|
||||
request.setDoneEvent(self.hook)
|
||||
request.setPythonObject((cb, i))
|
||||
i+=1
|
||||
self.loader.saveAsync(request)
|
||||
cb.requests[request] = True
|
||||
cb.requests.add(request)
|
||||
self.__requests[request] = (cb, i)
|
||||
i += 1
|
||||
return cb
|
||||
|
||||
|
||||
|
|
@ -496,7 +499,7 @@ class Loader(DirectObject):
|
|||
phaseChecker(modelPath, loaderOptions)
|
||||
|
||||
font = FontPool.loadFont(modelPath)
|
||||
if font == None:
|
||||
if font is None:
|
||||
if not okMissing:
|
||||
message = 'Could not load font file: %s' % (modelPath)
|
||||
raise IOError(message)
|
||||
|
|
@ -506,21 +509,21 @@ class Loader(DirectObject):
|
|||
|
||||
# The following properties may only be set for dynamic fonts.
|
||||
if hasattr(font, "setPointSize"):
|
||||
if pointSize != None:
|
||||
if pointSize is not None:
|
||||
font.setPointSize(pointSize)
|
||||
if pixelsPerUnit != None:
|
||||
if pixelsPerUnit is not None:
|
||||
font.setPixelsPerUnit(pixelsPerUnit)
|
||||
if scaleFactor != None:
|
||||
if scaleFactor is not None:
|
||||
font.setScaleFactor(scaleFactor)
|
||||
if textureMargin != None:
|
||||
if textureMargin is not None:
|
||||
font.setTextureMargin(textureMargin)
|
||||
if polyMargin != None:
|
||||
if polyMargin is not None:
|
||||
font.setPolyMargin(polyMargin)
|
||||
if minFilter != None:
|
||||
if minFilter is not None:
|
||||
font.setMinfilter(minFilter)
|
||||
if magFilter != None:
|
||||
if magFilter is not None:
|
||||
font.setMagfilter(magFilter)
|
||||
if anisotropicDegree != None:
|
||||
if anisotropicDegree is not None:
|
||||
font.setAnisotropicDegree(anisotropicDegree)
|
||||
if color:
|
||||
font.setFg(color)
|
||||
|
|
@ -577,10 +580,10 @@ class Loader(DirectObject):
|
|||
the texture and the number of expected mipmap images.
|
||||
|
||||
If minfilter or magfilter is not None, they should be a symbol
|
||||
like Texture.FTLinear or Texture.FTNearest. (minfilter may be
|
||||
further one of the Mipmap filter type symbols.) These specify
|
||||
the filter mode that will automatically be applied to the
|
||||
texture when it is loaded. Note that this setting may
|
||||
like SamplerState.FTLinear or SamplerState.FTNearest. (minfilter
|
||||
may be further one of the Mipmap filter type symbols.) These
|
||||
specify the filter mode that will automatically be applied to
|
||||
the texture when it is loaded. Note that this setting may
|
||||
override the texture's existing settings, even if it has
|
||||
already been loaded. See egg-texture-cards for a more robust
|
||||
way to apply per-texture filter types and settings.
|
||||
|
|
@ -596,7 +599,7 @@ class Loader(DirectObject):
|
|||
left image and '1' for the right image. Larger numbers are
|
||||
also allowed if you need more than two views.
|
||||
"""
|
||||
if loaderOptions == None:
|
||||
if loaderOptions is None:
|
||||
loaderOptions = LoaderOptions()
|
||||
else:
|
||||
loaderOptions = LoaderOptions(loaderOptions)
|
||||
|
|
@ -657,7 +660,7 @@ class Loader(DirectObject):
|
|||
numbered 8 - 15 will be part of the right eye view.
|
||||
"""
|
||||
assert Loader.notify.debug("Loading 3-D texture: %s" % (texturePattern))
|
||||
if loaderOptions == None:
|
||||
if loaderOptions is None:
|
||||
loaderOptions = LoaderOptions()
|
||||
else:
|
||||
loaderOptions = LoaderOptions(loaderOptions)
|
||||
|
|
@ -684,6 +687,63 @@ class Loader(DirectObject):
|
|||
|
||||
return texture
|
||||
|
||||
def load2DTextureArray(self, texturePattern, readMipmaps = False, okMissing = False,
|
||||
minfilter = None, magfilter = None, anisotropicDegree = None,
|
||||
loaderOptions = None, multiview = None, numViews = 2):
|
||||
"""
|
||||
texturePattern is a string that contains a sequence of one or
|
||||
more hash characters ('#'), which will be filled in with the
|
||||
z-height number. Returns a 2-D Texture array object, suitable
|
||||
for rendering array of textures.
|
||||
|
||||
okMissing should be True to indicate the method should return
|
||||
None if the texture file is not found. If it is False, the
|
||||
method will raise an exception if the texture file is not
|
||||
found or cannot be loaded.
|
||||
|
||||
If readMipmaps is True, then the filename string must contain
|
||||
two sequences of hash characters; the first group is filled in
|
||||
with the z-height number, and the second group with the mipmap
|
||||
index number.
|
||||
|
||||
If multiview is true, it indicates to load a multiview or
|
||||
stereo texture. In this case, numViews should also be
|
||||
specified (the default is 2), and the sequence of texture
|
||||
images will be divided into numViews views. The total
|
||||
z-height will be (numImages / numViews). For instance, if you
|
||||
read 16 images with numViews = 2, then you have created a
|
||||
stereo multiview image, with z = 8. In this example, images
|
||||
numbered 0 - 7 will be part of the left eye view, and images
|
||||
numbered 8 - 15 will be part of the right eye view.
|
||||
"""
|
||||
assert Loader.notify.debug("Loading 2-D texture array: %s" % (texturePattern))
|
||||
if loaderOptions is None:
|
||||
loaderOptions = LoaderOptions()
|
||||
else:
|
||||
loaderOptions = LoaderOptions(loaderOptions)
|
||||
if multiview is not None:
|
||||
flags = loaderOptions.getTextureFlags()
|
||||
if multiview:
|
||||
flags |= LoaderOptions.TFMultiview
|
||||
else:
|
||||
flags &= ~LoaderOptions.TFMultiview
|
||||
loaderOptions.setTextureFlags(flags)
|
||||
loaderOptions.setTextureNumViews(numViews)
|
||||
|
||||
texture = TexturePool.load2dTextureArray(texturePattern, readMipmaps, loaderOptions)
|
||||
if not texture and not okMissing:
|
||||
message = 'Could not load 2-D texture array: %s' % (texturePattern)
|
||||
raise IOError(message)
|
||||
|
||||
if minfilter is not None:
|
||||
texture.setMinfilter(minfilter)
|
||||
if magfilter is not None:
|
||||
texture.setMagfilter(magfilter)
|
||||
if anisotropicDegree is not None:
|
||||
texture.setAnisotropicDegree(anisotropicDegree)
|
||||
|
||||
return texture
|
||||
|
||||
def loadCubeMap(self, texturePattern, readMipmaps = False, okMissing = False,
|
||||
minfilter = None, magfilter = None, anisotropicDegree = None,
|
||||
loaderOptions = None, multiview = None):
|
||||
|
|
@ -711,7 +771,7 @@ class Loader(DirectObject):
|
|||
and each six images will define a new view.
|
||||
"""
|
||||
assert Loader.notify.debug("Loading cube map: %s" % (texturePattern))
|
||||
if loaderOptions == None:
|
||||
if loaderOptions is None:
|
||||
loaderOptions = LoaderOptions()
|
||||
else:
|
||||
loaderOptions = LoaderOptions(loaderOptions)
|
||||
|
|
@ -821,13 +881,12 @@ class Loader(DirectObject):
|
|||
# callback (passing it the sounds on the parameter list).
|
||||
|
||||
cb = Loader.Callback(len(soundList), gotList, callback, extraArgs)
|
||||
for i in range(len(soundList)):
|
||||
soundPath = soundList[i]
|
||||
for i, soundPath in enumerate(soundList):
|
||||
request = AudioLoadRequest(manager, soundPath, positional)
|
||||
request.setDoneEvent(self.hook)
|
||||
request.setPythonObject((cb, i))
|
||||
self.loader.loadAsync(request)
|
||||
cb.requests[request] = True
|
||||
cb.requests.add(request)
|
||||
self.__requests[request] = (cb, i)
|
||||
return cb
|
||||
|
||||
def unloadSfx(self, sfx):
|
||||
|
|
@ -852,7 +911,7 @@ class Loader(DirectObject):
|
|||
return shader
|
||||
|
||||
def unloadShader(self, shaderPath):
|
||||
if (shaderPath != None):
|
||||
if shaderPath is not None:
|
||||
ShaderPool.releaseShader(shaderPath)
|
||||
|
||||
def asyncFlattenStrong(self, model, inPlace = True,
|
||||
|
|
@ -886,14 +945,14 @@ class Loader(DirectObject):
|
|||
gotList = True
|
||||
|
||||
cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
|
||||
i=0
|
||||
i = 0
|
||||
for model in modelList:
|
||||
request = ModelFlattenRequest(model.node())
|
||||
request.setDoneEvent(self.hook)
|
||||
request.setPythonObject((cb, i))
|
||||
i+=1
|
||||
self.loader.loadAsync(request)
|
||||
cb.requests[request] = True
|
||||
cb.requests.add(request)
|
||||
self.__requests[request] = (cb, i)
|
||||
i += 1
|
||||
return cb
|
||||
|
||||
def __asyncFlattenDone(self, models,
|
||||
|
|
@ -907,7 +966,7 @@ class Loader(DirectObject):
|
|||
orig = origModelList[i].node()
|
||||
flat = models[i].node()
|
||||
orig.copyAllProperties(flat)
|
||||
orig.replaceNode(flat)
|
||||
flat.replaceNode(orig)
|
||||
|
||||
if callback:
|
||||
if gotList:
|
||||
|
|
@ -921,16 +980,23 @@ class Loader(DirectObject):
|
|||
of loaded objects, and call the appropriate callback when it's
|
||||
time."""
|
||||
|
||||
cb, i = request.getPythonObject()
|
||||
if cb.cancelled:
|
||||
if request not in self.__requests:
|
||||
return
|
||||
|
||||
del cb.requests[request]
|
||||
cb, i = self.__requests[request]
|
||||
if cb.cancelled:
|
||||
# Shouldn't be here.
|
||||
del self.__requests[request]
|
||||
return
|
||||
|
||||
cb.requests.discard(request)
|
||||
if not cb.requests:
|
||||
del self.__requests[request]
|
||||
|
||||
object = None
|
||||
if hasattr(request, "getModel"):
|
||||
node = request.getModel()
|
||||
if (node != None):
|
||||
if node is not None:
|
||||
object = NodePath(node)
|
||||
|
||||
elif hasattr(request, "getSound"):
|
||||
|
|
|
|||
|
|
@ -127,10 +127,6 @@ class ShowBase(DirectObject.DirectObject):
|
|||
## just before Python is about to shut down.
|
||||
self.finalExitCallbacks = []
|
||||
|
||||
Task.TaskManager.taskTimerVerbose = self.config.GetBool('task-timer-verbose', 0)
|
||||
Task.TaskManager.extendedExceptions = self.config.GetBool('extended-exceptions', 0)
|
||||
Task.TaskManager.pStatsTasks = self.config.GetBool('pstats-tasks', 0)
|
||||
|
||||
# Set up the TaskManager to reset the PStats clock back
|
||||
# whenever we resume from a pause. This callback function is
|
||||
# a little hacky, but we can't call it directly from within
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
/runp3d
|
||||
|
|
@ -984,7 +984,10 @@ class Freezer:
|
|||
try:
|
||||
self.__loadModule(mdef)
|
||||
except ImportError as ex:
|
||||
print("Unknown module: %s (%s)" % (mdef.moduleName, str(ex)))
|
||||
message = "Unknown module: %s" % (mdef.moduleName)
|
||||
if str(ex) != "No module named " + str(mdef.moduleName):
|
||||
message += " (%s)" % (ex)
|
||||
print(message)
|
||||
|
||||
# Also attempt to import any implicit modules. If any of
|
||||
# these fail to import, we don't really care.
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ def start_new_thread(function, args, kwargs = {}, name = None):
|
|||
name = 'PythonThread-%s' % (threadId)
|
||||
|
||||
thread = core.PythonThread(threadFunc, [threadId], name, name)
|
||||
thread.setPythonData(threadId)
|
||||
thread.setPythonIndex(threadId)
|
||||
_threads[threadId] = (thread, {}, None)
|
||||
|
||||
thread.start(core.TPNormal, False)
|
||||
|
|
@ -121,7 +121,7 @@ def _add_thread(thread, wrapper):
|
|||
threadId = _nextThreadId
|
||||
_nextThreadId += 1
|
||||
|
||||
thread.setPythonData(threadId)
|
||||
thread.setPythonIndex(threadId)
|
||||
_threads[threadId] = (thread, {}, wrapper)
|
||||
return threadId
|
||||
|
||||
|
|
@ -133,8 +133,8 @@ def _get_thread_wrapper(thread, wrapperClass):
|
|||
is not one, creates an instance of the indicated wrapperClass
|
||||
instead. """
|
||||
|
||||
threadId = thread.getPythonData()
|
||||
if threadId is None:
|
||||
threadId = thread.getPythonIndex()
|
||||
if threadId == -1:
|
||||
# The thread has never been assigned a threadId. Go assign one.
|
||||
|
||||
global _nextThreadId
|
||||
|
|
@ -143,7 +143,7 @@ def _get_thread_wrapper(thread, wrapperClass):
|
|||
threadId = _nextThreadId
|
||||
_nextThreadId += 1
|
||||
|
||||
thread.setPythonData(threadId)
|
||||
thread.setPythonIndex(threadId)
|
||||
wrapper = wrapperClass(thread, threadId)
|
||||
_threads[threadId] = (thread, {}, wrapper)
|
||||
return wrapper
|
||||
|
|
@ -169,8 +169,8 @@ def _get_thread_locals(thread, i):
|
|||
""" Returns the locals dictionary for the indicated thread. If
|
||||
there is not one, creates an empty dictionary. """
|
||||
|
||||
threadId = thread.getPythonData()
|
||||
if threadId is None:
|
||||
threadId = thread.getPythonIndex()
|
||||
if threadId == -1:
|
||||
# The thread has never been assigned a threadId. Go assign one.
|
||||
|
||||
global _nextThreadId
|
||||
|
|
@ -179,7 +179,7 @@ def _get_thread_locals(thread, i):
|
|||
threadId = _nextThreadId
|
||||
_nextThreadId += 1
|
||||
|
||||
thread.setPythonData(threadId)
|
||||
thread.setPythonIndex(threadId)
|
||||
locals = {}
|
||||
_threads[threadId] = (thread, locals, None)
|
||||
return locals.setdefault(i, {})
|
||||
|
|
@ -205,9 +205,9 @@ def _remove_thread_id(threadId):
|
|||
_threadsLock.acquire()
|
||||
try:
|
||||
thread, locals, wrapper = _threads[threadId]
|
||||
assert thread.getPythonData() == threadId
|
||||
assert thread.getPythonIndex() == threadId
|
||||
del _threads[threadId]
|
||||
thread.setPythonData(None)
|
||||
thread.setPythonIndex(-1)
|
||||
|
||||
finally:
|
||||
_threadsLock.release()
|
||||
|
|
|
|||
|
|
@ -102,7 +102,10 @@ Task.DtoolClassDict['loop'] = staticmethod(loop)
|
|||
class TaskManager:
|
||||
notify = directNotify.newCategory("TaskManager")
|
||||
|
||||
extendedExceptions = False
|
||||
taskTimerVerbose = ConfigVariableBool('task-timer-verbose', False)
|
||||
extendedExceptions = ConfigVariableBool('extended-exceptions', False)
|
||||
pStatsTasks = ConfigVariableBool('pstats-tasks', False)
|
||||
|
||||
MaxEpochSpeed = 1.0/30.0
|
||||
|
||||
def __init__(self):
|
||||
|
|
|
|||
|
|
@ -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/
|
||||
|
|
@ -6,6 +6,7 @@ This issue fixes several bugs that were still found in 1.9.2.
|
|||
* Fix crash using wx/tkinter on Mac as long as want-wx/tk is set
|
||||
* Fix loading models from 'models' package with models/ prefix
|
||||
* Fix random crashes in task system
|
||||
* Fix various race conditions causing threading issues
|
||||
* Fix memory leaks in BulletTriangleMesh
|
||||
* Fix loading old models with MovingPart<LMatrix4f>
|
||||
* Improve performance of CPU vertex animation somewhat
|
||||
|
|
@ -17,6 +18,36 @@ This issue fixes several bugs that were still found in 1.9.2.
|
|||
* Improve performance of texture load and store operations
|
||||
* Fix crashes with pbuffers on Intel cards on Windows
|
||||
* Support for Autodesk Maya 2016.5
|
||||
* Add shadow-depth-bits config var to control shadow map depth
|
||||
* Fix cull issue when rendering cube map (or any multi-lens setup)
|
||||
* Fix crash rendering with the same camera to different contexts
|
||||
* Fix compile error when making static build with DX9 renderer
|
||||
* Fix assertion when using aux render targets in DX9
|
||||
* Work around Cg bug generating invalid ASM for saturated tex loads
|
||||
* Fix issues with certain Cg shader inputs in DX9
|
||||
* Support uint8 index buffers in DX9
|
||||
* Fix occasional frame lag when loading a big model asynchronously
|
||||
* Fix interrogate parsing issue with "const static"
|
||||
* Add back missing libp3pystub.a to Mac OS X SDK
|
||||
* Fix RAM caching of 2D texture arrays
|
||||
* Fix Ctrl+C interrupt propagation to runtime applications
|
||||
* Support for InvSphere, Box and Tube solids in bam2egg
|
||||
* Preserve "intangible" and "level" collide flags in bam2egg
|
||||
* Add normalized() method to vectors
|
||||
* asyncFlattenStrong with inPlace=True caused node to disappear
|
||||
* Fix asyncFlattenStrong called on nodes without parent
|
||||
* Fix is_playing() check when playing an animation backwards
|
||||
* Windows installer no longer clears %PATH% if longer than 1024 chars
|
||||
* Fix inoperative -tbn/-tbnall/-tbnauto options in egg-optchar
|
||||
* Fix tinydisplay texture errors on shutdown
|
||||
* Fix mipmap filtering issues in tinydisplay renderer
|
||||
* Fix exception when creating intervals before ShowBase is started
|
||||
* Fix rare X11 .ico cursor bug; also now supports PNG-compressed icons
|
||||
* Add keyword argument support to make() methods such as Shader.make()
|
||||
* Fix compilation errors with Bullet 2.84
|
||||
* Fix exception when trying to pickle NodePathCollection objects
|
||||
* Fix error when trying to raise vectors to a power
|
||||
* GLSL: fix error when legacy matrix generator inputs are mat3
|
||||
|
||||
------------------------ RELEASE 1.9.2 ------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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 '}'
|
||||
{
|
||||
|
|
@ -783,6 +805,11 @@ storage_class:
|
|||
empty
|
||||
{
|
||||
$$ = 0;
|
||||
}
|
||||
| KW_CONST storage_class
|
||||
{
|
||||
// This isn't really a storage class, but it helps with parsing.
|
||||
$$ = $2 | (int)CPPInstance::SC_const;
|
||||
}
|
||||
| KW_EXTERN storage_class
|
||||
{
|
||||
|
|
@ -861,10 +888,22 @@ attribute_specifier:
|
|||
;
|
||||
|
||||
type_like_declaration:
|
||||
multiple_var_declaration
|
||||
storage_class var_type_decl
|
||||
{
|
||||
/* multiple_var_declaration adds itself to the scope. */
|
||||
// We don't need to push/pop type, because we can't nest
|
||||
// type_like_declaration.
|
||||
if ($2->as_type_declaration()) {
|
||||
current_type = $2->as_type_declaration()->_type;
|
||||
} else {
|
||||
current_type = $2->as_type();
|
||||
}
|
||||
push_storage_class($1);
|
||||
}
|
||||
multiple_instance_identifiers
|
||||
{
|
||||
pop_storage_class();
|
||||
}
|
||||
|
||||
| storage_class type_decl ';'
|
||||
{
|
||||
// We don't really care about the storage class here. In fact, it's
|
||||
|
|
@ -891,39 +930,6 @@ type_like_declaration:
|
|||
}
|
||||
}
|
||||
| using_declaration
|
||||
;
|
||||
|
||||
multiple_var_declaration:
|
||||
storage_class var_type_decl
|
||||
{
|
||||
// We don't need to push/pop type, because we can't nest
|
||||
// multiple_var_declarations.
|
||||
if ($2->as_type_declaration()) {
|
||||
current_type = $2->as_type_declaration()->_type;
|
||||
} else {
|
||||
current_type = $2->as_type();
|
||||
}
|
||||
push_storage_class($1);
|
||||
}
|
||||
multiple_instance_identifiers
|
||||
{
|
||||
pop_storage_class();
|
||||
}
|
||||
| storage_class KW_CONST var_type_decl
|
||||
{
|
||||
// We don't need to push/pop type, because we can't nest
|
||||
// multiple_var_declarations.
|
||||
if ($3->as_type_declaration()) {
|
||||
current_type = $3->as_type_declaration()->_type;
|
||||
} else {
|
||||
current_type = $3->as_type();
|
||||
}
|
||||
push_storage_class($1);
|
||||
}
|
||||
multiple_const_instance_identifiers
|
||||
{
|
||||
pop_storage_class();
|
||||
}
|
||||
|
||||
/* We don't need to include a rule for variables that point to
|
||||
functions, because we get those from the function_prototype
|
||||
|
|
@ -933,6 +939,9 @@ multiple_var_declaration:
|
|||
multiple_instance_identifiers:
|
||||
instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
|
||||
{
|
||||
if (current_storage_class & CPPInstance::SC_const) {
|
||||
$1->add_modifier(IIT_const);
|
||||
}
|
||||
CPPInstance *inst = new CPPInstance(current_type, $1,
|
||||
current_storage_class,
|
||||
@1.file);
|
||||
|
|
@ -941,27 +950,9 @@ multiple_instance_identifiers:
|
|||
}
|
||||
| instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' multiple_instance_identifiers
|
||||
{
|
||||
CPPInstance *inst = new CPPInstance(current_type, $1,
|
||||
current_storage_class,
|
||||
@1.file);
|
||||
inst->set_initializer($2);
|
||||
current_scope->add_declaration(inst, global_scope, current_lexer, @1);
|
||||
}
|
||||
;
|
||||
|
||||
multiple_const_instance_identifiers:
|
||||
instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
|
||||
{
|
||||
$1->add_modifier(IIT_const);
|
||||
CPPInstance *inst = new CPPInstance(current_type, $1,
|
||||
current_storage_class,
|
||||
@1.file);
|
||||
inst->set_initializer($2);
|
||||
current_scope->add_declaration(inst, global_scope, current_lexer, @1);
|
||||
}
|
||||
| instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' multiple_const_instance_identifiers
|
||||
{
|
||||
$1->add_modifier(IIT_const);
|
||||
if (current_storage_class & CPPInstance::SC_const) {
|
||||
$1->add_modifier(IIT_const);
|
||||
}
|
||||
CPPInstance *inst = new CPPInstance(current_type, $1,
|
||||
current_storage_class,
|
||||
@1.file);
|
||||
|
|
@ -986,21 +977,6 @@ typedef_declaration:
|
|||
typedef_instance_identifiers
|
||||
{
|
||||
pop_storage_class();
|
||||
}
|
||||
| storage_class KW_CONST var_type_decl
|
||||
{
|
||||
// We don't need to push/pop type, because we can't nest
|
||||
// multiple_var_declarations.
|
||||
if ($3->as_type_declaration()) {
|
||||
current_type = $3->as_type_declaration()->_type;
|
||||
} else {
|
||||
current_type = $3->as_type();
|
||||
}
|
||||
push_storage_class($1);
|
||||
}
|
||||
typedef_const_instance_identifiers
|
||||
{
|
||||
pop_storage_class();
|
||||
}
|
||||
| storage_class function_prototype maybe_initialize_or_function_body
|
||||
{
|
||||
|
|
@ -1019,29 +995,18 @@ typedef_declaration:
|
|||
typedef_instance_identifiers:
|
||||
instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
|
||||
{
|
||||
if (current_storage_class & CPPInstance::SC_const) {
|
||||
$1->add_modifier(IIT_const);
|
||||
}
|
||||
CPPType *target_type = current_type;
|
||||
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
|
||||
current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
|
||||
}
|
||||
| instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_instance_identifiers
|
||||
{
|
||||
CPPType *target_type = current_type;
|
||||
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
|
||||
current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
|
||||
}
|
||||
;
|
||||
|
||||
typedef_const_instance_identifiers:
|
||||
instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
|
||||
{
|
||||
$1->add_modifier(IIT_const);
|
||||
CPPType *target_type = current_type;
|
||||
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
|
||||
current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
|
||||
}
|
||||
| instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_const_instance_identifiers
|
||||
{
|
||||
$1->add_modifier(IIT_const);
|
||||
if (current_storage_class & CPPInstance::SC_const) {
|
||||
$1->add_modifier(IIT_const);
|
||||
}
|
||||
CPPType *target_type = current_type;
|
||||
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
|
||||
current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
|
||||
|
|
@ -1244,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 '(' ')'
|
||||
{
|
||||
|
|
@ -1272,6 +1249,10 @@ function_post:
|
|||
| function_post KW_THROW '(' name ')'
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| function_post KW_THROW '(' name ELLIPSIS ')'
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
/* | function_post '[' '[' attribute_specifiers ']' ']'
|
||||
{
|
||||
|
|
@ -1475,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
|
||||
{
|
||||
|
|
@ -1504,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;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1524,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);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1604,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
|
||||
{
|
||||
|
|
@ -1842,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
|
||||
{
|
||||
|
|
@ -1970,10 +2009,79 @@ formal_parameter_identifier:
|
|||
}
|
||||
;
|
||||
|
||||
parameter_pack_identifier:
|
||||
ELLIPSIS
|
||||
{
|
||||
$$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
|
||||
$$->_packed = true;
|
||||
}
|
||||
| ELLIPSIS name
|
||||
{
|
||||
$$ = new CPPInstanceIdentifier($2);
|
||||
$$->_packed = true;
|
||||
}
|
||||
| KW_CONST parameter_pack_identifier %prec UNARY
|
||||
{
|
||||
$$ = $2;
|
||||
$$->add_modifier(IIT_const);
|
||||
}
|
||||
| KW_VOLATILE parameter_pack_identifier %prec UNARY
|
||||
{
|
||||
$$ = $2;
|
||||
$$->add_modifier(IIT_volatile);
|
||||
}
|
||||
| '*' parameter_pack_identifier %prec UNARY
|
||||
{
|
||||
$$ = $2;
|
||||
$$->add_modifier(IIT_pointer);
|
||||
}
|
||||
| '&' parameter_pack_identifier %prec UNARY
|
||||
{
|
||||
$$ = $2;
|
||||
$$->add_modifier(IIT_reference);
|
||||
}
|
||||
| ANDAND parameter_pack_identifier %prec UNARY
|
||||
{
|
||||
$$ = $2;
|
||||
$$->add_modifier(IIT_rvalue_reference);
|
||||
}
|
||||
| SCOPING '*' parameter_pack_identifier %prec UNARY
|
||||
{
|
||||
$$ = $3;
|
||||
$$->add_scoped_pointer_modifier($1);
|
||||
}
|
||||
| parameter_pack_identifier '[' optional_const_expr ']'
|
||||
{
|
||||
$$ = $1;
|
||||
$$->add_array_modifier($3);
|
||||
}
|
||||
| '(' parameter_pack_identifier ')' '(' function_parameter_list ')' function_post
|
||||
{
|
||||
$$ = $2;
|
||||
$$->add_modifier(IIT_paren);
|
||||
$$->add_func_modifier($5, $7);
|
||||
}
|
||||
| '(' parameter_pack_identifier ')'
|
||||
{
|
||||
$$ = $2;
|
||||
$$->add_modifier(IIT_paren);
|
||||
}
|
||||
;
|
||||
|
||||
not_paren_empty_instance_identifier:
|
||||
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
|
||||
{
|
||||
|
|
@ -2016,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
|
||||
{
|
||||
|
|
@ -2150,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
|
||||
{
|
||||
|
|
@ -2157,6 +2285,17 @@ type:
|
|||
}
|
||||
;
|
||||
|
||||
type_pack:
|
||||
TYPEPACK_IDENTIFIER
|
||||
{
|
||||
$$ = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if ($$ == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert($$ != NULL);
|
||||
}
|
||||
;
|
||||
|
||||
type_decl:
|
||||
simple_type
|
||||
{
|
||||
|
|
@ -2244,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
|
||||
{
|
||||
|
|
@ -2308,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
|
||||
{
|
||||
|
|
@ -2336,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);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -2750,6 +2918,7 @@ element:
|
|||
| CHAR_TOK
|
||||
| IDENTIFIER
|
||||
| TYPENAME_IDENTIFIER
|
||||
| TYPEPACK_IDENTIFIER
|
||||
| SCOPING
|
||||
| SIMPLE_IDENTIFIER
|
||||
| ELLIPSIS | OROR | ANDAND
|
||||
|
|
@ -2768,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
|
||||
{
|
||||
}
|
||||
| '+' | '-' | '*' | '/' | '&' | '|' | '^' | '!' | '~' | '=' | '%'
|
||||
|
|
@ -2840,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
|
||||
{
|
||||
|
|
@ -3078,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
|
||||
{
|
||||
|
|
@ -3295,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));
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -3333,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
|
||||
{
|
||||
|
|
@ -3575,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);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -3607,6 +3863,10 @@ name:
|
|||
| TYPENAME_IDENTIFIER
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| TYPEPACK_IDENTIFIER
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| KW_FINAL
|
||||
{
|
||||
|
|
@ -3652,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";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()->
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@ public:
|
|||
SC_deleted = 0x8000,
|
||||
|
||||
SC_thread_local = 0x10000,
|
||||
|
||||
// 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);
|
||||
|
|
|
|||
|
|
@ -370,10 +370,8 @@ save_expansion(const string &exp, const vector_string ¶meter_names) {
|
|||
|
||||
// Is this identifier one of our parameters?
|
||||
int pnum = -1;
|
||||
bool va_args = false;
|
||||
|
||||
if (ident == "__VA_ARGS__") {
|
||||
va_args = true;
|
||||
// C99-style variadics, ie. #define macro(...) __VA_ARGS__
|
||||
pnum = _variadic_param;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -806,7 +814,7 @@ expand_manifests(const string &input_expr, bool expand_undefined,
|
|||
Manifests::const_iterator mi = _manifests.find(ident);
|
||||
if (mi != _manifests.end()) {
|
||||
const CPPManifest *manifest = (*mi).second;
|
||||
expand_manifest_inline(expr, q, p, (*mi).second);
|
||||
expand_manifest_inline(expr, q, p, manifest);
|
||||
manifest_found = true;
|
||||
|
||||
} else if (expand_undefined && ident != "true" && ident != "false") {
|
||||
|
|
@ -951,7 +959,7 @@ internal_get_next_token() {
|
|||
case ',':
|
||||
if (_paren_nesting <= 0) {
|
||||
_state = S_end_nested;
|
||||
return CPPToken::eof();
|
||||
return CPPToken(0, loc);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -959,7 +967,7 @@ internal_get_next_token() {
|
|||
if (_paren_nesting <= 0) {
|
||||
_parsing_template_params = false;
|
||||
_state = S_end_nested;
|
||||
return CPPToken::eof();
|
||||
return CPPToken(0, loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1192,8 +1200,6 @@ skip_c_comment(int c) {
|
|||
|
||||
} else {
|
||||
CPPFile first_file = get_file();
|
||||
int first_line_number = get_line_number();
|
||||
int first_col_number = get_col_number() - 2;
|
||||
|
||||
while (c != EOF) {
|
||||
if (c == '*') {
|
||||
|
|
@ -1641,7 +1647,7 @@ handle_include_directive(const string &args, const YYLTYPE &loc) {
|
|||
_last_c = '\0';
|
||||
|
||||
// If it was explicitly named on the command-line, mark it S_local.
|
||||
filename.make_absolute();
|
||||
filename.make_canonical();
|
||||
if (_explicit_files.count(filename)) {
|
||||
source = CPPFile::S_local;
|
||||
}
|
||||
|
|
@ -1816,8 +1822,9 @@ get_identifier(int c) {
|
|||
type = CPPExpression::T_u16string;
|
||||
} else if (name == "U") {
|
||||
type = CPPExpression::T_u32string;
|
||||
} else {
|
||||
type = CPPExpression::T_string;
|
||||
}
|
||||
|
||||
get();
|
||||
string str = scan_quoted(c);
|
||||
|
||||
|
|
@ -2452,11 +2459,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;
|
||||
|
|
@ -2491,6 +2514,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;
|
||||
|
|
@ -2752,7 +2776,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);
|
||||
|
|
@ -2761,36 +2785,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;
|
||||
|
|
|
|||
|
|
@ -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,62 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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,6 +431,14 @@ 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.
|
||||
*/
|
||||
|
|
@ -399,6 +602,139 @@ is_copy_constructible(CPPVisibility min_vis) const {
|
|||
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;
|
||||
}
|
||||
|
||||
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 +756,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 +819,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 +850,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 +879,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 +908,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 {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ CPPToken(int token, int line_number, int col_number,
|
|||
*/
|
||||
CPPToken::
|
||||
CPPToken(int token, const YYLTYPE &loc, const string &str, const YYSTYPE &val) :
|
||||
_token(token), _lloc(loc), _lval(val)
|
||||
_token(token), _lval(val), _lloc(loc)
|
||||
{
|
||||
_lval.str = str;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -70,23 +70,25 @@
|
|||
#else
|
||||
// #pragma message("VC 6.0")
|
||||
#endif
|
||||
#endif /* WIN32_VC */
|
||||
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
// Use NODEFAULT to optimize a switch() stmt to tell MSVC to automatically go
|
||||
// to the final untested case after it has failed all the other cases (i.e.
|
||||
// 'assume at least one of the cases is always true')
|
||||
#ifdef _DEBUG
|
||||
# define NODEFAULT default: assert(0);
|
||||
#define NODEFAULT default: assert(0); break;
|
||||
#elif defined(_MSC_VER)
|
||||
#define NODEFAULT default: __assume(0); // special VC keyword
|
||||
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || __has_builtin(__builtin_unreachable)
|
||||
#define NODEFAULT default: __builtin_unreachable();
|
||||
#else
|
||||
# define NODEFAULT default: __assume(0); // special VC keyword
|
||||
#define NODEFAULT
|
||||
#endif
|
||||
|
||||
#else /* if !WIN32_VC */
|
||||
#ifdef _DEBUG
|
||||
# define NODEFAULT default: assert(0);
|
||||
#else
|
||||
# define NODEFAULT
|
||||
#endif
|
||||
#endif /* WIN32_VC */
|
||||
|
||||
/*
|
||||
include win32 defns for everything up to WinServer2003, and assume
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue