Merge remote-tracking branch 'upstream/master'

Conflicts:
    makepanda/makepanda.py
This commit is contained in:
John Cote 2024-09-06 22:40:10 -04:00
commit f2b421e005
338 changed files with 2143 additions and 83860 deletions

View File

@ -40,7 +40,7 @@ jobs:
eigen: NO
- profile: macos-eigen-coverage-unity-xcode
os: macOS-11
os: macOS-12
config: Coverage
unity: YES
generator: Xcode
@ -50,7 +50,7 @@ jobs:
eigen: YES
- profile: macos-nometa-standard-makefile
os: macOS-11
os: macOS-12
config: Standard
unity: NO
generator: Unix Makefiles
@ -361,7 +361,7 @@ jobs:
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
strategy:
matrix:
os: [ubuntu-20.04, windows-2019, macOS-11]
os: [ubuntu-20.04, windows-2019, macOS-12]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v1
@ -472,14 +472,6 @@ jobs:
sudo apt-get update
sudo apt-get install build-essential ninja-build bison flex
- name: Build Host Interrogate
shell: bash
run: |
mkdir -p host-build
cmake -S . -B host-build -DBUILD_DIRECT=OFF -DBUILD_PANDA=OFF -DBUILD_PANDATOOL=OFF -DBUILD_CONTRIB=OFF -DBUILD_DTOOL=ON -DBUILD_MODELS=OFF -DBUILD_SHARED_LIBS=OFF -DINTERROGATE_PYTHON_INTERFACE=OFF
cmake --build host-build --config Standard --parallel 4
echo host-build/bin >> $GITHUB_PATH
- name: Setup emsdk
uses: mymindstorm/setup-emsdk@v14
with:

View File

@ -4,10 +4,11 @@ This is a list of all the people who are contributing financially to Panda3D. I
## Bronze Sponsors
[<img src="https://www.panda3d.org/wp-content/uploads/2021/02/changecrab_logo.png" alt="ChangeCrab" height="48">](https://changecrab.com/) ![Bronze Sponsors](https://opencollective.com/panda3d/tiers/bronze-sponsor.svg?avatarHeight=48&width=600)
[<img src="https://www.panda3d.org/wp-content/uploads/2024/08/Route4MeLogo1185x300-2-1-1024x259.png" alt="Route4Me" height="48">](https://route4me.com/)
* [Daniel Stokes](https://opencollective.com/daniel-stokes)
* [David Rose](https://opencollective.com/david-rose)
* [Route4Me](https://route4me.com/)
## Benefactors

View File

@ -109,6 +109,7 @@ option(BUILD_DIRECT "Build the direct source tree." ON)
option(BUILD_PANDATOOL "Build the pandatool source tree." ON)
option(BUILD_CONTRIB "Build the contrib source tree." ON)
option(BUILD_MODELS "Build/install the built-in models." ON)
option(BUILD_TOOLS "Build binary tools." ON)
# Include Panda3D packages
if(BUILD_DTOOL)

View File

@ -2,11 +2,11 @@
[![OpenCollective](https://opencollective.com/panda3d/backers/badge.svg)](https://opencollective.com/panda3d)
[![OpenCollective](https://opencollective.com/panda3d/sponsors/badge.svg)](https://opencollective.com/panda3d)
<img src="https://avatars2.githubusercontent.com/u/590956?v=3&s=500" align="right" width="200"/>
Panda3D
=======
<img src="https://avatars2.githubusercontent.com/u/590956?v=3&s=500" align="right" width="200" />
Panda3D is a game engine, a framework for 3D rendering and game development for
Python and C++ programs. Panda3D is open-source and free for any purpose,
including commercial ventures, thanks to its
@ -168,7 +168,7 @@ Install the appropriate package for it (such as `python37` or `python38`) and
run the makepanda script with your chosen Python version:
```bash
python3.7 makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2
python3.11 makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2
```
If successful, this will produce a .pkg file in the root of the source

View File

@ -257,7 +257,7 @@ function(interrogate_sources target output database language_flags)
make_directory "${output_directory}"
COMMAND ${CMAKE_COMMAND} -E
make_directory "${database_directory}"
COMMAND host_interrogate
COMMAND interrogate
-oc "${output}"
-od "${database}"
-srcdir "${srcdir}"
@ -272,7 +272,7 @@ function(interrogate_sources target output database language_flags)
${include_flags}
${scan_sources}
DEPENDS host_interrogate ${sources} ${extensions} ${nfiles}
DEPENDS interrogate ${sources} ${extensions} ${nfiles}
COMMENT "Interrogating ${target}")
# Propagate the target's compile definitions to the output file
@ -362,13 +362,13 @@ function(add_python_module module)
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}/${module}_module.cxx"
COMMAND ${CMAKE_COMMAND} -E
make_directory "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}"
COMMAND host_interrogate_module
COMMAND interrogate_module
-oc "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}/${module}_module.cxx"
-module ${module} -library ${modname}
${import_flags}
${INTERROGATE_MODULE_OPTIONS}
${IMOD_FLAGS} ${infiles_rel}
DEPENDS host_interrogate_module ${infiles_abs}
DEPENDS interrogate_module ${infiles_abs}
COMMENT "Generating module ${module}")
# CMake chokes on ${CMAKE_CFG_INTDIR} in source paths when unity builds are

View File

@ -737,6 +737,13 @@ class Actor(DirectObject, NodePath):
else:
return None
def getPlayMode(self, animName=None, partName=None):
if self.__animControlDict:
controls = self.getAnimControls(animName, partName, onlyPlaying=False)
if controls:
return controls[0].getPlayMode()
return None
def hasLOD(self):
"""
Return 1 if the actor has LODs, 0 otherwise
@ -1762,7 +1769,7 @@ class Actor(DirectObject, NodePath):
return None
def getAnimControls(self, animName=None, partName=None, lodName=None,
allowAsyncBind = True):
allowAsyncBind = True, onlyPlaying = True):
"""getAnimControls(self, string, string=None, string=None)
Returns a list of the AnimControls that represent the given
@ -1840,7 +1847,7 @@ class Actor(DirectObject, NodePath):
# get all playing animations
for thisPart, animDict in animDictItems:
for anim in animDict.values():
if anim.animControl and anim.animControl.isPlaying():
if anim.animControl and (not onlyPlaying or anim.animControl.isPlaying()):
controls.append(anim.animControl)
else:
# get the named animation(s) only.
@ -2660,3 +2667,4 @@ class Actor(DirectObject, NodePath):
get_base_frame_rate = getBaseFrameRate
remove_anim_control_dict = removeAnimControlDict
load_anims_on_all_lods = loadAnimsOnAllLODs
get_play_mode = getPlayMode

View File

@ -1,3 +1,7 @@
if(NOT BUILD_TOOLS)
return()
endif()
add_executable(p3dcparse dcparse.cxx)
target_link_libraries(p3dcparse p3direct)
install(TARGETS p3dcparse EXPORT Direct COMPONENT Direct DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@ -179,7 +179,7 @@ dc_cleanup_parser() {
# endif
# endif
#include "dcParser.yxx.h"
#include "dcParser.h"
/* Symbol kind. */
enum yysymbol_kind_t
{

View File

@ -264,6 +264,54 @@ class Transitions:
self.iris = base.loader.loadModel(self.IrisModelName)
self.iris.setPos(0, 0, 0)
def getIrisInIval(self, t=0.5, finishIval=None, blendType='noBlend'):
"""
Returns an interval without starting it. This is particularly useful in
cutscenes, so when the cutsceneIval is escaped out of we can finish the iris immediately
"""
self.noTransitions()
self.loadIris()
scale = 0.18 * max(base.a2dRight, base.a2dTop)
transitionIval = Sequence(Func(self.iris.reparentTo, ShowBaseGlobal.aspect2d, DGG.FADE_SORT_INDEX),
LerpScaleInterval(self.iris, t,
scale = scale,
startScale = 0.01,
blendType=blendType),
Func(self.iris.detachNode),
Func(self.__finishTransition),
name = self.irisTaskName,
)
if finishIval:
transitionIval.append(finishIval)
return transitionIval
def getIrisOutIval(self, t=0.5, finishIval=None, blendType='noBlend'):
"""
Create a sequence that lerps the iris out, then
parents the iris to hidden
"""
self.noTransitions()
self.loadIris()
self.loadFade() # we need this to cover up the hole.
scale = 0.18 * max(base.a2dRight, base.a2dTop)
transitionIval = Sequence(Func(self.iris.reparentTo, ShowBaseGlobal.aspect2d, DGG.FADE_SORT_INDEX),
LerpScaleInterval(self.iris, t,
scale = 0.01,
startScale = scale,
blendType=blendType),
Func(self.iris.detachNode),
# Use the fade to cover up the hole that the iris would leave
Func(self.fadeOut, 0),
Func(self.__finishTransition),
name = self.irisTaskName,
)
if finishIval:
transitionIval.append(finishIval)
return transitionIval
def irisIn(self, t=0.5, finishIval=None, blendType = 'noBlend'):
"""
Play an iris in transition over t seconds.
@ -271,25 +319,13 @@ class Transitions:
of the iris polygon up so it looks like we iris in. When the
scale lerp is finished, it parents the iris polygon to hidden.
"""
self.noTransitions()
self.loadIris()
if t == 0:
self.iris.detachNode()
fut = AsyncFuture()
fut.setResult(None)
return fut
else:
self.iris.reparentTo(ShowBaseGlobal.aspect2d, DGG.FADE_SORT_INDEX)
scale = 0.18 * max(base.a2dRight, base.a2dTop)
self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
scale = scale,
startScale = 0.01,
blendType=blendType),
Func(self.iris.detachNode),
Func(self.__finishTransition),
name = self.irisTaskName,
)
self.transitionIval = self.getIrisInIval(t, finishIval, blendType)
self.__transitionFuture = AsyncFuture()
if finishIval:
self.transitionIval.append(finishIval)
@ -304,9 +340,6 @@ class Transitions:
lerp is finished, it leaves the iris polygon covering the
aspect2d plane until you irisIn or call noIris.
"""
self.noTransitions()
self.loadIris()
self.loadFade() # we need this to cover up the hole.
if t == 0:
self.iris.detachNode()
self.fadeOut(0)
@ -314,19 +347,7 @@ class Transitions:
fut.setResult(None)
return fut
else:
self.iris.reparentTo(ShowBaseGlobal.aspect2d, DGG.FADE_SORT_INDEX)
scale = 0.18 * max(base.a2dRight, base.a2dTop)
self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
scale = 0.01,
startScale = scale,
blendType=blendType),
Func(self.iris.detachNode),
# Use the fade to cover up the hole that the iris would leave
Func(self.fadeOut, 0),
Func(self.__finishTransition),
name = self.irisTaskName,
)
self.transitionIval = self.getIrisOutIval(t, finishIval, blendType)
self.__transitionFuture = AsyncFuture()
if finishIval:
self.transitionIval.append(finishIval)

View File

@ -2,11 +2,9 @@
include(LocalSetup.cmake)
# Include dtool source directories
add_subdirectory(src/cppparser)
add_subdirectory(src/dconfig)
add_subdirectory(src/dtoolbase)
add_subdirectory(src/dtoolutil)
add_subdirectory(src/interrogate)
add_subdirectory(src/interrogatedb)
add_subdirectory(src/prc)

View File

@ -221,12 +221,6 @@ mark_as_advanced(DEFAULT_PRC_DIR PRC_DIR_ENVVARS PRC_PATH_ENVVARS
# The following options relate to interrogate, the tool that is
# used to generate bindings for non-C++ languages.
option(WANT_INTERROGATE
"Do you want to include Interrogate in the installation? This
program reads C++ source files and generates bindings for another
language. If you won't be building interfaces for other languages,
you don't need the program." ON)
cmake_dependent_option(INTERROGATE_PYTHON_INTERFACE
"Do you want to generate a Python-callable interrogate interface?
This is only necessary if you plan to make calls into Panda from a
@ -249,8 +243,79 @@ option(INTERROGATE_VERBOSE
"Set this if you would like interrogate to generate advanced
debugging information." OFF)
set(_default_build_interrogate OFF)
if (INTERROGATE_C_INTERFACE OR INTERROGATE_PYTHON_INTERFACE)
set(_default_build_interrogate ON)
endif()
option(BUILD_INTERROGATE
"Do you want to build interrogate from source? This is necessary
if you wish to build Python or other bindings around Panda3D's C++
interface. Set this to false if you already have a compatible
version of interrogate installed." ${_default_build_interrogate})
mark_as_advanced(INTERROGATE_OPTIONS)
if(BUILD_INTERROGATE)
include(ExternalProject)
set(_interrogate_dir "${PROJECT_BINARY_DIR}/interrogate")
ExternalProject_Add(
panda3d-interrogate
GIT_REPOSITORY https://github.com/panda3d/interrogate.git
GIT_TAG e297384b30f1eae8ab839ec096fc3bb6bdb3edeb
PREFIX ${_interrogate_dir}
CMAKE_ARGS
-DHAVE_PYTHON=OFF
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
EXCLUDE_FROM_ALL ON
BUILD_BYPRODUCTS "${_interrogate_dir}/bin/interrogate"
"${_interrogate_dir}/bin/interrogate_module"
)
add_executable(interrogate IMPORTED GLOBAL)
add_dependencies(interrogate panda3d-interrogate)
set_target_properties(interrogate PROPERTIES IMPORTED_LOCATION "${_interrogate_dir}/bin/interrogate")
add_executable(interrogate_module IMPORTED GLOBAL)
add_dependencies(interrogate_module panda3d-interrogate)
set_target_properties(interrogate_module PROPERTIES IMPORTED_LOCATION "${_interrogate_dir}/bin/interrogate_module")
else()
find_program(INTERROGATE_EXECUTABLE interrogate)
find_program(INTERROGATE_MODULE_EXECUTABLE interrogate_module)
add_executable(interrogate IMPORTED GLOBAL)
if(INTERROGATE_EXECUTABLE)
set_target_properties(interrogate PROPERTIES
IMPORTED_LOCATION "${INTERROGATE_EXECUTABLE}")
elseif(INTERROGATE_PYTHON_INTERFACE OR INTERROGATE_C_INTERFACE)
message(FATAL_ERROR
"Requested interrogate bindings, but interrogate not found. Set "
"BUILD_INTERROGATE to build interrogate from source, or set "
"INTERROGATE_EXECUTABLE to the location of this tool.")
endif()
add_executable(interrogate_module IMPORTED GLOBAL)
if(INTERROGATE_MODULE_EXECUTABLE)
set_target_properties(interrogate_module PROPERTIES
IMPORTED_LOCATION "${INTERROGATE_MODULE_EXECUTABLE}")
elseif(INTERROGATE_PYTHON_INTERFACE)
message(FATAL_ERROR
"Requested interrogate bindings, but interrogate not found. Set "
"BUILD_INTERROGATE to build interrogate from source, or set "
"INTERROGATE_MODULE_EXECUTABLE to the location of this tool.")
endif()
endif()
#
# The following options have to do with optional debugging features.
#

View File

@ -24,9 +24,6 @@
/* Define to use doubles for most numbers, intead of single-precision floats. */
#cmakedefine STDFLOAT_DOUBLE
/* Define if we have built libRocket available and built with Python support. */
#cmakedefine HAVE_ROCKET_PYTHON
/* Define if we have ARToolKit available. */
#cmakedefine HAVE_ARTOOLKIT

View File

@ -1,46 +0,0 @@
set(P3CPPPARSER_HEADERS
cppAttributeList.h
cppArrayType.h cppBison.yxx cppBisonDefs.h
cppClassTemplateParameter.h cppCommentBlock.h
cppClosureType.h cppConstType.h
cppDeclaration.h cppEnumType.h cppExpression.h
cppExpressionParser.h cppExtensionType.h cppFile.h
cppFunctionGroup.h cppFunctionType.h cppGlobals.h
cppIdentifier.h cppInstance.h cppInstanceIdentifier.h
cppMakeProperty.h cppMakeSeq.h cppManifest.h
cppNameComponent.h cppNamespace.h
cppParameterList.h cppParser.h cppPointerType.h
cppPreprocessor.h cppReferenceType.h cppScope.h
cppSimpleType.h cppStructType.h cppTBDType.h
cppTemplateParameterList.h cppTemplateScope.h cppToken.h
cppType.h cppTypeDeclaration.h cppTypeParser.h
cppTypeProxy.h cppTypedefType.h cppUsing.h cppVisibility.h
)
set(P3CPPPARSER_SOURCES
cppAttributeList.cxx
cppArrayType.cxx ${CMAKE_CURRENT_BINARY_DIR}/cppBison.cxx
cppClassTemplateParameter.cxx
cppCommentBlock.cxx cppClosureType.cxx cppConstType.cxx cppDeclaration.cxx
cppEnumType.cxx cppExpression.cxx cppExpressionParser.cxx
cppExtensionType.cxx cppFile.cxx cppFunctionGroup.cxx
cppFunctionType.cxx cppGlobals.cxx cppIdentifier.cxx
cppInstance.cxx cppInstanceIdentifier.cxx
cppMakeProperty.cxx cppMakeSeq.cxx cppManifest.cxx
cppNameComponent.cxx cppNamespace.cxx cppParameterList.cxx
cppParser.cxx cppPointerType.cxx cppPreprocessor.cxx
cppReferenceType.cxx cppScope.cxx cppSimpleType.cxx
cppStructType.cxx cppTBDType.cxx
cppTemplateParameterList.cxx cppTemplateScope.cxx
cppToken.cxx cppType.cxx cppTypeDeclaration.cxx
cppTypeParser.cxx cppTypeProxy.cxx cppTypedefType.cxx
cppUsing.cxx cppVisibility.cxx
)
add_bison_target(cppBison.cxx cppBison.yxx DEFINES cppBison.h PREFIX cppyy)
composite_sources(p3cppParser P3CPPPARSER_SOURCES)
add_library(p3cppParser STATIC ${P3CPPPARSER_HEADERS} ${P3CPPPARSER_SOURCES})
target_link_libraries(p3cppParser p3dtool)
install(TARGETS p3cppParser EXPORT Core COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@ -1,269 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppArrayType.cxx
* @author drose
* @date 1999-10-19
*/
#include "cppArrayType.h"
#include "cppExpression.h"
#include "cppPointerType.h"
/**
*
*/
CPPArrayType::
CPPArrayType(CPPType *element_type, CPPExpression *bounds) :
CPPType(CPPFile()),
_element_type(element_type),
_bounds(bounds)
{
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which
* has not yet been instantiated.
*/
bool CPPArrayType::
is_fully_specified() const {
return CPPType::is_fully_specified() &&
_element_type->is_fully_specified();
}
/**
* If this CPPType object is a forward reference or other nonspecified
* reference to a type that might now be known a real type, returns the real
* type. Otherwise returns the type itself.
*/
CPPType *CPPArrayType::
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
CPPType *ptype = _element_type->resolve_type(current_scope, global_scope);
if (ptype != _element_type) {
CPPArrayType *rep = new CPPArrayType(*this);
rep->_element_type = ptype;
return CPPType::new_type(rep);
}
return this;
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPArrayType::
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.
*/
bool CPPArrayType::
is_trivial() const {
return _element_type->is_trivial();
}
/**
* Returns true if the type can be safely copied by memcpy or memmove.
*/
bool CPPArrayType::
is_trivially_copyable() const {
return _element_type->is_trivially_copyable();
}
/**
* Returns true if the type is default-constructible.
*/
bool CPPArrayType::
is_default_constructible() const {
return _bounds != nullptr && _element_type->is_default_constructible();
}
/**
* Returns true if the type is copy-constructible.
*/
bool CPPArrayType::
is_copy_constructible() const {
// This is technically not exactly true, but array data members do not
// prevent C++ implicit copy constructor generation rules, so we need to
// return true here.
// If this is a problem, we will need to create a separate method for the
// purpose of checking copyability as a data member.
return true;
}
/**
* Returns true if the type is copy-assignable.
*/
bool CPPArrayType::
is_copy_assignable() const {
// Same story as is_copy_constructible.
return true;
}
/**
* 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
* different pointers or somewhat different definitions. It's useful for
* parameter matching, etc.
*/
bool CPPArrayType::
is_equivalent(const CPPType &other) const {
const CPPArrayType *ot = ((CPPType *)&other)->as_array_type();
if (ot == nullptr) {
return CPPType::is_equivalent(other);
}
return _element_type->is_equivalent(*ot->_element_type);
}
/**
*
*/
CPPDeclaration *CPPArrayType::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
SubstDecl::const_iterator si = subst.find(this);
if (si != subst.end()) {
return (*si).second;
}
CPPArrayType *rep = new CPPArrayType(*this);
rep->_element_type =
_element_type->substitute_decl(subst, current_scope, global_scope)
->as_type();
if (_bounds != nullptr) {
rep->_bounds =
_bounds->substitute_decl(subst, current_scope, global_scope)
->as_expression();
}
if (rep->_element_type == _element_type &&
rep->_bounds == _bounds) {
delete rep;
rep = this;
}
rep = CPPType::new_type(rep)->as_array_type();
subst.insert(SubstDecl::value_type(this, rep));
return rep;
}
/**
*
*/
void CPPArrayType::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
/*
_element_type->output(out, indent_level, scope, complete);
out << "[";
if (_bounds != NULL) {
out << *_bounds;
}
out << "]";
*/
output_instance(out, indent_level, scope, complete, "", "");
}
/**
* Formats a C++-looking line that defines an instance of the given type, with
* the indicated name. In most cases this will be "type name", but some types
* have special exceptions.
*/
void CPPArrayType::
output_instance(std::ostream &out, int indent_level, CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const {
std::ostringstream brackets;
brackets << "[";
if (_bounds != nullptr) {
brackets << *_bounds;
}
brackets << "]";
if (!_attributes.is_empty()) {
brackets << " " << _attributes;
}
std::string bracketsstr = brackets.str();
_element_type->output_instance(out, indent_level, scope, complete,
prename, name + bracketsstr);
}
/**
*
*/
CPPDeclaration::SubType CPPArrayType::
get_subtype() const {
return ST_array;
}
/**
*
*/
CPPArrayType *CPPArrayType::
as_array_type() {
return this;
}
/**
* Called by CPPDeclaration() to determine whether this type is equivalent to
* another type of the same type.
*/
bool CPPArrayType::
is_equal(const CPPDeclaration *other) const {
const CPPArrayType *ot = ((CPPDeclaration *)other)->as_array_type();
assert(ot != nullptr);
if (_bounds != nullptr && ot->_bounds != nullptr) {
if (*_bounds != *ot->_bounds) {
return false;
}
} else if ((_bounds == nullptr) != (ot->_bounds == nullptr)) {
return false;
}
return *_element_type == *ot->_element_type;
}
/**
* Called by CPPDeclaration() to determine whether this type should be ordered
* before another type of the same type, in an arbitrary but fixed ordering.
*/
bool CPPArrayType::
is_less(const CPPDeclaration *other) const {
const CPPArrayType *ot = ((CPPDeclaration *)other)->as_array_type();
assert(ot != nullptr);
if (_bounds != nullptr && ot->_bounds != nullptr) {
if (*_bounds != *ot->_bounds) {
return *_bounds < *ot->_bounds;
}
} else if ((_bounds == nullptr) != (ot->_bounds == nullptr)) {
return _bounds < ot->_bounds;
}
if (*_element_type != *ot->_element_type) {
return *_element_type < *ot->_element_type;
}
return false;
}

View File

@ -1,65 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppArrayType.h
* @author drose
* @date 1999-10-19
*/
#ifndef CPPARRAYTYPE_H
#define CPPARRAYTYPE_H
#include "dtoolbase.h"
#include "cppType.h"
class CPPExpression;
/**
*
*/
class CPPArrayType : public CPPType {
public:
CPPArrayType(CPPType *element_type, CPPExpression *bounds);
CPPType *_element_type;
CPPExpression *_bounds;
virtual bool is_fully_specified() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
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_trivially_copyable() const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_copy_assignable() const;
virtual bool is_equivalent(const CPPType &other) const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual void output_instance(std::ostream &out, int indent_level,
CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const;
virtual SubType get_subtype() const;
virtual CPPArrayType *as_array_type();
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
};
#endif

View File

@ -1,196 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppAttributeList.cxx
* @author rdb
* @date 2022-10-23
*/
#include "cppAttributeList.h"
#include "cppExpression.h"
#include "cppIdentifier.h"
#include "cppType.h"
/**
* Returns true if no attributes have been defined.
*/
bool CPPAttributeList::
is_empty() const {
return _attributes.empty() && _alignas == nullptr;
}
/**
* Returns true if the attribute list has an attribute with the given name.
*/
bool CPPAttributeList::
has_attribute(const std::string &name) const {
for (const Attribute &attr : _attributes) {
if (attr._ident->get_fully_scoped_name() == name) {
return true;
}
}
return false;
}
/**
*
*/
bool CPPAttributeList::
operator == (const CPPAttributeList &other) const {
if (_attributes.size() != other._attributes.size()) {
return false;
}
if ((_alignas != nullptr) != (other._alignas != nullptr)) {
return false;
}
if (_alignas != nullptr && *_alignas != *other._alignas) {
return false;
}
for (size_t i = 0; i < _attributes.size(); ++i) {
if (_attributes[i]._ident != other._attributes[i]._ident) {
return false;
}
if (_attributes[i]._reason != other._attributes[i]._reason) {
return false;
}
}
return true;
}
/**
*
*/
bool CPPAttributeList::
operator != (const CPPAttributeList &other) const {
return !(*this == other);
}
/**
*
*/
bool CPPAttributeList::
operator < (const CPPAttributeList &other) const {
if (_attributes.size() != other._attributes.size()) {
return _attributes.size() < other._attributes.size();
}
if ((_alignas != nullptr) != (other._alignas != nullptr)) {
return _alignas == nullptr;
}
if (_alignas != nullptr && *_alignas != *other._alignas) {
return *_alignas < *other._alignas;
}
for (size_t i = 0; i < _attributes.size(); ++i) {
if (_attributes[i]._ident != other._attributes[i]._ident) {
return _attributes[i]._ident < other._attributes[i]._ident;
}
if (_attributes[i]._reason != other._attributes[i]._reason) {
return _attributes[i]._reason < other._attributes[i]._reason;
}
}
return false;
}
/**
* Adds an attribute.
*/
void CPPAttributeList::
add_attribute(CPPIdentifier *ident) {
_attributes.push_back({ident});
}
/**
* Adds an attribute.
*/
void CPPAttributeList::
add_attribute(CPPIdentifier *ident, std::string reason) {
_attributes.push_back({ident, std::move(reason)});
}
/**
* Adds an alignas specifier.
*/
void CPPAttributeList::
add_alignas(int size) {
if (_alignas == nullptr || size >= _alignas->evaluate().as_integer()) {
_alignas = new CPPExpression(size);
}
}
/**
* Adds an alignas specifier.
*/
void CPPAttributeList::
add_alignas(CPPType *type) {
CPPExpression expr = CPPExpression::alignof_func(type);
if (_alignas == nullptr || expr.evaluate().as_integer() > _alignas->evaluate().as_integer()) {
_alignas = new CPPExpression(expr);
}
}
/**
* Adds an alignas specifier.
*/
void CPPAttributeList::
add_alignas(CPPExpression *expr) {
if (_alignas == nullptr || expr->evaluate().as_integer() > _alignas->evaluate().as_integer()) {
_alignas = expr;
}
}
/**
* Merges the other list into this one.
*/
void CPPAttributeList::
add_attributes_from(const CPPAttributeList &other) {
for (const Attribute &attr : other._attributes) {
_attributes.push_back(attr);
}
if (other._alignas != nullptr) {
add_alignas(other._alignas);
}
}
/**
*
*/
void CPPAttributeList::
output(std::ostream &out, CPPScope *scope) const {
Attributes::const_iterator it = _attributes.begin();
if (it != _attributes.end()) {
out << "[[";
(*it)._ident->output(out, scope);
if (!(*it)._reason.empty()) {
out << "(" << (*it)._reason << ")";
}
for (++it; it != _attributes.end(); ++it) {
out << ", ";
(*it)._ident->output(out, scope);
if (!(*it)._reason.empty()) {
out << "(" << (*it)._reason << ")";
}
}
out << "]]";
if (_alignas != nullptr) {
out << " ";
}
}
if (_alignas != nullptr) {
out << "alignas(";
if (_alignas->_type == CPPExpression::T_alignof) {
_alignas->_u._typecast._to->output(out, 0, scope, false);
} else {
_alignas->output(out, 0, scope, false);
}
out << ")";
}
}

View File

@ -1,65 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppAttributeList.h
* @author rdb
* @date 2022-10-23
*/
#ifndef CPPATTRIBUTELIST_H
#define CPPATTRIBUTELIST_H
#include "dtoolbase.h"
#include <vector>
class CPPExpression;
class CPPIdentifier;
class CPPScope;
class CPPType;
/**
* A list of square-bracket attributes and/or alignas specifiers.
*/
class CPPAttributeList {
public:
bool is_empty() const;
bool has_attribute(const std::string &name) const;
bool operator == (const CPPAttributeList &other) const;
bool operator != (const CPPAttributeList &other) const;
bool operator < (const CPPAttributeList &other) const;
void add_attribute(CPPIdentifier *ident);
void add_attribute(CPPIdentifier *ident, std::string reason);
void add_alignas(int size);
void add_alignas(CPPType *type);
void add_alignas(CPPExpression *expr);
void add_attributes_from(const CPPAttributeList &other);
struct Attribute {
CPPIdentifier *_ident;
std::string _reason;
};
typedef std::vector<Attribute> Attributes;
Attributes _attributes;
CPPExpression *_alignas = nullptr;
void output(std::ostream &out, CPPScope *scope) const;
};
inline std::ostream &
operator << (std::ostream &out, const CPPAttributeList &alist) {
alist.output(out, nullptr);
return out;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,394 +0,0 @@
/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
# define YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int cppyydebug;
#endif
/* Token kinds. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
YYEMPTY = -2,
YYEOF = 0, /* "end of file" */
YYerror = 256, /* error */
YYUNDEF = 257, /* "invalid token" */
REAL = 258, /* REAL */
INTEGER = 259, /* INTEGER */
CHAR_TOK = 260, /* CHAR_TOK */
SIMPLE_STRING = 261, /* SIMPLE_STRING */
SIMPLE_IDENTIFIER = 262, /* SIMPLE_IDENTIFIER */
STRING_LITERAL = 263, /* STRING_LITERAL */
CUSTOM_LITERAL = 264, /* CUSTOM_LITERAL */
IDENTIFIER = 265, /* IDENTIFIER */
TYPENAME_IDENTIFIER = 266, /* TYPENAME_IDENTIFIER */
TYPEPACK_IDENTIFIER = 267, /* TYPEPACK_IDENTIFIER */
SCOPING = 268, /* SCOPING */
TYPEDEFNAME = 269, /* TYPEDEFNAME */
ELLIPSIS = 270, /* ELLIPSIS */
OROR = 271, /* OROR */
ANDAND = 272, /* ANDAND */
EQCOMPARE = 273, /* EQCOMPARE */
NECOMPARE = 274, /* NECOMPARE */
LECOMPARE = 275, /* LECOMPARE */
GECOMPARE = 276, /* GECOMPARE */
SPACESHIP = 277, /* SPACESHIP */
LSHIFT = 278, /* LSHIFT */
RSHIFT = 279, /* RSHIFT */
POINTSAT_STAR = 280, /* POINTSAT_STAR */
DOT_STAR = 281, /* DOT_STAR */
UNARY = 282, /* UNARY */
UNARY_NOT = 283, /* UNARY_NOT */
UNARY_NEGATE = 284, /* UNARY_NEGATE */
UNARY_MINUS = 285, /* UNARY_MINUS */
UNARY_PLUS = 286, /* UNARY_PLUS */
UNARY_STAR = 287, /* UNARY_STAR */
UNARY_REF = 288, /* UNARY_REF */
POINTSAT = 289, /* POINTSAT */
SCOPE = 290, /* SCOPE */
PLUSPLUS = 291, /* PLUSPLUS */
MINUSMINUS = 292, /* MINUSMINUS */
TIMESEQUAL = 293, /* TIMESEQUAL */
DIVIDEEQUAL = 294, /* DIVIDEEQUAL */
MODEQUAL = 295, /* MODEQUAL */
PLUSEQUAL = 296, /* PLUSEQUAL */
MINUSEQUAL = 297, /* MINUSEQUAL */
OREQUAL = 298, /* OREQUAL */
ANDEQUAL = 299, /* ANDEQUAL */
XOREQUAL = 300, /* XOREQUAL */
LSHIFTEQUAL = 301, /* LSHIFTEQUAL */
RSHIFTEQUAL = 302, /* RSHIFTEQUAL */
ATTR_LEFT = 303, /* ATTR_LEFT */
ATTR_RIGHT = 304, /* ATTR_RIGHT */
KW_ALIGNAS = 305, /* KW_ALIGNAS */
KW_ALIGNOF = 306, /* KW_ALIGNOF */
KW_AUTO = 307, /* KW_AUTO */
KW_BEGIN_PUBLISH = 308, /* KW_BEGIN_PUBLISH */
KW_BLOCKING = 309, /* KW_BLOCKING */
KW_BOOL = 310, /* KW_BOOL */
KW_BUILTIN_VA_LIST = 311, /* KW_BUILTIN_VA_LIST */
KW_CATCH = 312, /* KW_CATCH */
KW_CHAR = 313, /* KW_CHAR */
KW_CHAR8_T = 314, /* KW_CHAR8_T */
KW_CHAR16_T = 315, /* KW_CHAR16_T */
KW_CHAR32_T = 316, /* KW_CHAR32_T */
KW_CLASS = 317, /* KW_CLASS */
KW_CONST = 318, /* KW_CONST */
KW_CONSTEVAL = 319, /* KW_CONSTEVAL */
KW_CONSTEXPR = 320, /* KW_CONSTEXPR */
KW_CONSTINIT = 321, /* KW_CONSTINIT */
KW_CONST_CAST = 322, /* KW_CONST_CAST */
KW_DECLTYPE = 323, /* KW_DECLTYPE */
KW_DEFAULT = 324, /* KW_DEFAULT */
KW_DELETE = 325, /* KW_DELETE */
KW_DOUBLE = 326, /* KW_DOUBLE */
KW_DYNAMIC_CAST = 327, /* KW_DYNAMIC_CAST */
KW_ELSE = 328, /* KW_ELSE */
KW_END_PUBLISH = 329, /* KW_END_PUBLISH */
KW_ENUM = 330, /* KW_ENUM */
KW_EXTENSION = 331, /* KW_EXTENSION */
KW_EXTERN = 332, /* KW_EXTERN */
KW_EXPLICIT = 333, /* KW_EXPLICIT */
KW_EXPLICIT_LPAREN = 334, /* KW_EXPLICIT_LPAREN */
KW_PUBLISHED = 335, /* KW_PUBLISHED */
KW_FALSE = 336, /* KW_FALSE */
KW_FINAL = 337, /* KW_FINAL */
KW_FLOAT = 338, /* KW_FLOAT */
KW_FRIEND = 339, /* KW_FRIEND */
KW_FOR = 340, /* KW_FOR */
KW_GOTO = 341, /* KW_GOTO */
KW_HAS_VIRTUAL_DESTRUCTOR = 342, /* KW_HAS_VIRTUAL_DESTRUCTOR */
KW_IF = 343, /* KW_IF */
KW_INLINE = 344, /* KW_INLINE */
KW_INT = 345, /* KW_INT */
KW_IS_ABSTRACT = 346, /* KW_IS_ABSTRACT */
KW_IS_BASE_OF = 347, /* KW_IS_BASE_OF */
KW_IS_CLASS = 348, /* KW_IS_CLASS */
KW_IS_CONSTRUCTIBLE = 349, /* KW_IS_CONSTRUCTIBLE */
KW_IS_CONVERTIBLE_TO = 350, /* KW_IS_CONVERTIBLE_TO */
KW_IS_DESTRUCTIBLE = 351, /* KW_IS_DESTRUCTIBLE */
KW_IS_EMPTY = 352, /* KW_IS_EMPTY */
KW_IS_ENUM = 353, /* KW_IS_ENUM */
KW_IS_FINAL = 354, /* KW_IS_FINAL */
KW_IS_FUNDAMENTAL = 355, /* KW_IS_FUNDAMENTAL */
KW_IS_POD = 356, /* KW_IS_POD */
KW_IS_POLYMORPHIC = 357, /* KW_IS_POLYMORPHIC */
KW_IS_STANDARD_LAYOUT = 358, /* KW_IS_STANDARD_LAYOUT */
KW_IS_TRIVIAL = 359, /* KW_IS_TRIVIAL */
KW_IS_TRIVIALLY_COPYABLE = 360, /* KW_IS_TRIVIALLY_COPYABLE */
KW_IS_UNION = 361, /* KW_IS_UNION */
KW_LONG = 362, /* KW_LONG */
KW_MAKE_MAP_KEYS_SEQ = 363, /* KW_MAKE_MAP_KEYS_SEQ */
KW_MAKE_MAP_PROPERTY = 364, /* KW_MAKE_MAP_PROPERTY */
KW_MAKE_PROPERTY = 365, /* KW_MAKE_PROPERTY */
KW_MAKE_PROPERTY2 = 366, /* KW_MAKE_PROPERTY2 */
KW_MAKE_SEQ = 367, /* KW_MAKE_SEQ */
KW_MAKE_SEQ_PROPERTY = 368, /* KW_MAKE_SEQ_PROPERTY */
KW_MUTABLE = 369, /* KW_MUTABLE */
KW_NAMESPACE = 370, /* KW_NAMESPACE */
KW_NEW = 371, /* KW_NEW */
KW_NOEXCEPT = 372, /* KW_NOEXCEPT */
KW_NOEXCEPT_LPAREN = 373, /* KW_NOEXCEPT_LPAREN */
KW_NULLPTR = 374, /* KW_NULLPTR */
KW_OPERATOR = 375, /* KW_OPERATOR */
KW_OVERRIDE = 376, /* KW_OVERRIDE */
KW_PRIVATE = 377, /* KW_PRIVATE */
KW_PROTECTED = 378, /* KW_PROTECTED */
KW_PUBLIC = 379, /* KW_PUBLIC */
KW_REGISTER = 380, /* KW_REGISTER */
KW_REINTERPRET_CAST = 381, /* KW_REINTERPRET_CAST */
KW_RESTRICT = 382, /* KW_RESTRICT */
KW_RETURN = 383, /* KW_RETURN */
KW_SHORT = 384, /* KW_SHORT */
KW_SIGNED = 385, /* KW_SIGNED */
KW_SIZEOF = 386, /* KW_SIZEOF */
KW_STATIC = 387, /* KW_STATIC */
KW_STATIC_ASSERT = 388, /* KW_STATIC_ASSERT */
KW_STATIC_CAST = 389, /* KW_STATIC_CAST */
KW_STRUCT = 390, /* KW_STRUCT */
KW_TEMPLATE = 391, /* KW_TEMPLATE */
KW_THREAD_LOCAL = 392, /* KW_THREAD_LOCAL */
KW_THROW = 393, /* KW_THROW */
KW_TRUE = 394, /* KW_TRUE */
KW_TRY = 395, /* KW_TRY */
KW_TYPEDEF = 396, /* KW_TYPEDEF */
KW_TYPEID = 397, /* KW_TYPEID */
KW_TYPENAME = 398, /* KW_TYPENAME */
KW_UNDERLYING_TYPE = 399, /* KW_UNDERLYING_TYPE */
KW_UNION = 400, /* KW_UNION */
KW_UNSIGNED = 401, /* KW_UNSIGNED */
KW_USING = 402, /* KW_USING */
KW_VIRTUAL = 403, /* KW_VIRTUAL */
KW_VOID = 404, /* KW_VOID */
KW_VOLATILE = 405, /* KW_VOLATILE */
KW_WCHAR_T = 406, /* KW_WCHAR_T */
KW_WHILE = 407, /* KW_WHILE */
START_CPP = 408, /* START_CPP */
START_CONST_EXPR = 409, /* START_CONST_EXPR */
START_TYPE = 410 /* START_TYPE */
};
typedef enum yytokentype yytoken_kind_t;
#endif
/* Token kinds. */
#define YYEMPTY -2
#define YYEOF 0
#define YYerror 256
#define YYUNDEF 257
#define REAL 258
#define INTEGER 259
#define CHAR_TOK 260
#define SIMPLE_STRING 261
#define SIMPLE_IDENTIFIER 262
#define STRING_LITERAL 263
#define CUSTOM_LITERAL 264
#define IDENTIFIER 265
#define TYPENAME_IDENTIFIER 266
#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 SPACESHIP 277
#define LSHIFT 278
#define RSHIFT 279
#define POINTSAT_STAR 280
#define DOT_STAR 281
#define UNARY 282
#define UNARY_NOT 283
#define UNARY_NEGATE 284
#define UNARY_MINUS 285
#define UNARY_PLUS 286
#define UNARY_STAR 287
#define UNARY_REF 288
#define POINTSAT 289
#define SCOPE 290
#define PLUSPLUS 291
#define MINUSMINUS 292
#define TIMESEQUAL 293
#define DIVIDEEQUAL 294
#define MODEQUAL 295
#define PLUSEQUAL 296
#define MINUSEQUAL 297
#define OREQUAL 298
#define ANDEQUAL 299
#define XOREQUAL 300
#define LSHIFTEQUAL 301
#define RSHIFTEQUAL 302
#define ATTR_LEFT 303
#define ATTR_RIGHT 304
#define KW_ALIGNAS 305
#define KW_ALIGNOF 306
#define KW_AUTO 307
#define KW_BEGIN_PUBLISH 308
#define KW_BLOCKING 309
#define KW_BOOL 310
#define KW_BUILTIN_VA_LIST 311
#define KW_CATCH 312
#define KW_CHAR 313
#define KW_CHAR8_T 314
#define KW_CHAR16_T 315
#define KW_CHAR32_T 316
#define KW_CLASS 317
#define KW_CONST 318
#define KW_CONSTEVAL 319
#define KW_CONSTEXPR 320
#define KW_CONSTINIT 321
#define KW_CONST_CAST 322
#define KW_DECLTYPE 323
#define KW_DEFAULT 324
#define KW_DELETE 325
#define KW_DOUBLE 326
#define KW_DYNAMIC_CAST 327
#define KW_ELSE 328
#define KW_END_PUBLISH 329
#define KW_ENUM 330
#define KW_EXTENSION 331
#define KW_EXTERN 332
#define KW_EXPLICIT 333
#define KW_EXPLICIT_LPAREN 334
#define KW_PUBLISHED 335
#define KW_FALSE 336
#define KW_FINAL 337
#define KW_FLOAT 338
#define KW_FRIEND 339
#define KW_FOR 340
#define KW_GOTO 341
#define KW_HAS_VIRTUAL_DESTRUCTOR 342
#define KW_IF 343
#define KW_INLINE 344
#define KW_INT 345
#define KW_IS_ABSTRACT 346
#define KW_IS_BASE_OF 347
#define KW_IS_CLASS 348
#define KW_IS_CONSTRUCTIBLE 349
#define KW_IS_CONVERTIBLE_TO 350
#define KW_IS_DESTRUCTIBLE 351
#define KW_IS_EMPTY 352
#define KW_IS_ENUM 353
#define KW_IS_FINAL 354
#define KW_IS_FUNDAMENTAL 355
#define KW_IS_POD 356
#define KW_IS_POLYMORPHIC 357
#define KW_IS_STANDARD_LAYOUT 358
#define KW_IS_TRIVIAL 359
#define KW_IS_TRIVIALLY_COPYABLE 360
#define KW_IS_UNION 361
#define KW_LONG 362
#define KW_MAKE_MAP_KEYS_SEQ 363
#define KW_MAKE_MAP_PROPERTY 364
#define KW_MAKE_PROPERTY 365
#define KW_MAKE_PROPERTY2 366
#define KW_MAKE_SEQ 367
#define KW_MAKE_SEQ_PROPERTY 368
#define KW_MUTABLE 369
#define KW_NAMESPACE 370
#define KW_NEW 371
#define KW_NOEXCEPT 372
#define KW_NOEXCEPT_LPAREN 373
#define KW_NULLPTR 374
#define KW_OPERATOR 375
#define KW_OVERRIDE 376
#define KW_PRIVATE 377
#define KW_PROTECTED 378
#define KW_PUBLIC 379
#define KW_REGISTER 380
#define KW_REINTERPRET_CAST 381
#define KW_RESTRICT 382
#define KW_RETURN 383
#define KW_SHORT 384
#define KW_SIGNED 385
#define KW_SIZEOF 386
#define KW_STATIC 387
#define KW_STATIC_ASSERT 388
#define KW_STATIC_CAST 389
#define KW_STRUCT 390
#define KW_TEMPLATE 391
#define KW_THREAD_LOCAL 392
#define KW_THROW 393
#define KW_TRUE 394
#define KW_TRY 395
#define KW_TYPEDEF 396
#define KW_TYPEID 397
#define KW_TYPENAME 398
#define KW_UNDERLYING_TYPE 399
#define KW_UNION 400
#define KW_UNSIGNED 401
#define KW_USING 402
#define KW_VIRTUAL 403
#define KW_VOID 404
#define KW_VOLATILE 405
#define KW_WCHAR_T 406
#define KW_WHILE 407
#define START_CPP 408
#define START_CONST_EXPR 409
#define START_TYPE 410
/* Value type. */
/* Location type. */
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE YYLTYPE;
struct YYLTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
};
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1
#endif
int cppyyparse (void);
#endif /* !YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED */

File diff suppressed because it is too large Load Diff

View File

@ -1,124 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppBisonDefs.h
* @author drose
* @date 1999-01-17
*/
#ifndef CPPBISON_H
#define CPPBISON_H
// This header file defines the interface to the yacc (actually, bison) parser
// and grammar. None of these interfaces are intended to be used directly;
// they're defined here strictly to be used by the CPPParser and
// CPPExpressionParser classes.
#include "dtoolbase.h"
#include <string>
#include "cppAttributeList.h"
#include "cppClosureType.h"
#include "cppExtensionType.h"
#include "cppFile.h"
class CPPParser;
class CPPExpression;
class CPPPreprocessor;
class CPPDeclaration;
class CPPInstance;
class CPPType;
class CPPStructType;
class CPPEnumType;
class CPPSimpleType;
class CPPInstanceIdentifier;
class CPPParameterList;
class CPPTemplateParameterList;
class CPPScope;
class CPPIdentifier;
class CPPCaptureType;
void parse_cpp(CPPParser *cp);
CPPExpression *parse_const_expr(CPPPreprocessor *pp,
CPPScope *new_current_scope,
CPPScope *new_global_scope);
CPPType *parse_type(CPPPreprocessor *pp,
CPPScope *new_current_scope,
CPPScope *new_global_scope);
extern CPPScope *current_scope;
extern CPPScope *global_scope;
extern CPPPreprocessor *current_lexer;
// This structure holds the return value for each token. Traditionally, this
// is a union, and is declared with the %union declaration in the parser.y
// file, but unions are pretty worthless in C++ (you can't include an object
// that has member functions in a union), so we'll use a class instead. That
// means we need to declare it externally, here.
class cppyystype {
public:
std::string str;
CPPAttributeList attr_list;
union {
unsigned long long integer;
long double real;
CPPScope *scope;
CPPDeclaration *decl;
CPPInstance *instance;
CPPType *type;
CPPStructType *struct_type;
CPPEnumType *enum_type;
CPPSimpleType *simple_type;
CPPInstanceIdentifier *inst_ident;
CPPParameterList *param_list;
CPPTemplateParameterList *template_param_list;
CPPExtensionType::Type extension_enum;
CPPExpression *expr;
CPPIdentifier *identifier;
CPPClosureType *closure_type;
CPPClosureType::Capture *capture;
} u;
};
#define YYSTYPE cppyystype
// This structure takes advantage of a bison feature to track the exact
// location in the file of each token, for more useful error reporting. We
// define it up here so we can reference it in the lexer.
struct cppyyltype {
// Bison expects these members to be part of this struct.
int first_line;
int first_column;
int last_line;
int last_column;
// Early versions of bison (1.25 and earlier) expected these members to be
// in this struct as well.
int timestamp;
char *text;
// The remaining members are added for this application and have no meaning
// to bison.
CPPFile file;
};
#define YYLTYPE cppyyltype
// Beginning around bison 1.35 or so, we need to define this macro as well, to
// tell bison how to collect multiple locations together. (The default
// implementation copies only first_line through last_column, whereas here we
// use the struct assignment operator to copy all the members of the
// structure).
#define YYLLOC_DEFAULT(Current, Rhs, N) \
(Current) = (Rhs)[1]; \
(Current).last_line = (Rhs)[N].last_line; \
(Current).last_column = (Rhs)[N].last_column;
#endif

View File

@ -1,126 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppClassTemplateParameter.cxx
* @author drose
* @date 1999-10-28
*/
#include "cppClassTemplateParameter.h"
#include "cppIdentifier.h"
/**
*
*/
CPPClassTemplateParameter::
CPPClassTemplateParameter(CPPIdentifier *ident, CPPType *default_type) :
CPPType(CPPFile()),
_ident(ident),
_default_type(default_type),
_packed(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
* has not yet been instantiated.
*/
bool CPPClassTemplateParameter::
is_fully_specified() const {
return false;
}
/**
*
*/
void CPPClassTemplateParameter::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
if (complete) {
out << "class";
if (_packed) {
out << "...";
}
if (_ident != nullptr) {
out << " ";
_ident->output(out, scope);
}
if (_default_type) {
out << " = ";
_default_type->output(out, indent_level, scope, false);
}
} else {
_ident->output(out, scope);
}
}
/**
*
*/
CPPDeclaration::SubType CPPClassTemplateParameter::
get_subtype() const {
return ST_class_template_parameter;
}
/**
*
*/
CPPClassTemplateParameter *CPPClassTemplateParameter::
as_class_template_parameter() {
return this;
}
/**
* Called by CPPDeclaration() to determine whether this type is equivalent to
* another type of the same type.
*/
bool CPPClassTemplateParameter::
is_equal(const CPPDeclaration *other) const {
const CPPClassTemplateParameter *ot = ((CPPDeclaration *)other)->as_class_template_parameter();
assert(ot != nullptr);
if (_default_type != ot->_default_type) {
return false;
}
if (_packed != ot->_packed) {
return false;
}
if (_ident == nullptr || ot->_ident == nullptr) {
return _ident == ot->_ident;
}
return *_ident == *ot->_ident;
}
/**
* Called by CPPDeclaration() to determine whether this type should be ordered
* before another type of the same type, in an arbitrary but fixed ordering.
*/
bool CPPClassTemplateParameter::
is_less(const CPPDeclaration *other) const {
const CPPClassTemplateParameter *ot = ((CPPDeclaration *)other)->as_class_template_parameter();
assert(ot != nullptr);
if (_default_type != ot->_default_type) {
return _default_type < ot->_default_type;
}
if (_packed != ot->_packed) {
return _packed < ot->_packed;
}
if (_ident == nullptr || ot->_ident == nullptr) {
return _ident < ot->_ident;
}
return *_ident < *ot->_ident;
}

View File

@ -1,47 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppClassTemplateParameter.h
* @author drose
* @date 1999-10-28
*/
#ifndef CPPCLASSTEMPLATEPARAMETER_H
#define CPPCLASSTEMPLATEPARAMETER_H
#include "dtoolbase.h"
#include "cppType.h"
class CPPIdentifier;
/**
*
*/
class CPPClassTemplateParameter : public CPPType {
public:
CPPClassTemplateParameter(CPPIdentifier *ident,
CPPType *default_type = nullptr);
virtual bool is_fully_specified() const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPClassTemplateParameter *as_class_template_parameter();
CPPIdentifier *_ident;
CPPType *_default_type;
bool _packed;
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
};
#endif

View File

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

View File

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

View File

@ -1,14 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppCommentBlock.cxx
* @author drose
* @date 2000-08-15
*/
#include "cppCommentBlock.h"

View File

@ -1,41 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppCommentBlock.h
* @author drose
* @date 2000-08-15
*/
#ifndef CPPCOMMENTBLOCK_H
#define CPPCOMMENTBLOCK_H
#include "dtoolbase.h"
#include "cppFile.h"
#include <list>
/**
* This represents a comment appearing in the source code. The
* CPPPreprocessor collects these, and saves the complete list of comments
* encountered; it also stores a list of the comment blocks appearing before
* each declaration.
*/
class CPPCommentBlock {
public:
CPPFile _file;
int _line_number;
int _col_number;
int _last_line;
bool _c_style;
std::string _comment;
};
typedef std::list<CPPCommentBlock *> CPPComments;
#endif

View File

@ -1,240 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppConstType.cxx
* @author drose
* @date 1999-10-28
*/
#include "cppConstType.h"
/**
*
*/
CPPConstType::
CPPConstType(CPPType *wrapped_around) :
CPPType(CPPFile()),
_wrapped_around(wrapped_around)
{
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which
* has not yet been instantiated.
*/
bool CPPConstType::
is_fully_specified() const {
return CPPType::is_fully_specified() &&
_wrapped_around->is_fully_specified();
}
/**
*
*/
CPPDeclaration *CPPConstType::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
SubstDecl::const_iterator si = subst.find(this);
if (si != subst.end()) {
return (*si).second;
}
CPPConstType *rep = new CPPConstType(*this);
rep->_wrapped_around =
_wrapped_around->substitute_decl(subst, current_scope, global_scope)
->as_type();
if (rep->_wrapped_around == _wrapped_around) {
delete rep;
rep = this;
}
rep = CPPType::new_type(rep)->as_const_type();
subst.insert(SubstDecl::value_type(this, rep));
return rep;
}
/**
* If this CPPType object is a forward reference or other nonspecified
* reference to a type that might now be known a real type, returns the real
* type. Otherwise returns the type itself.
*/
CPPType *CPPConstType::
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
CPPType *ptype = _wrapped_around->resolve_type(current_scope, global_scope);
if (ptype != _wrapped_around) {
CPPConstType *rep = new CPPConstType(*this);
rep->_wrapped_around = ptype;
return CPPType::new_type(rep);
}
return this;
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPConstType::
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.
*/
bool CPPConstType::
is_trivial() const {
return _wrapped_around->is_trivial();
}
/**
* Returns true if the type can be safely copied by memcpy or memmove.
*/
bool CPPConstType::
is_trivially_copyable() const {
return _wrapped_around->is_trivially_copyable();
}
/**
* 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 _wrapped_around->is_default_constructible();
}
/**
* Returns true if the type is copy-constructible.
*/
bool CPPConstType::
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
* different pointers or somewhat different definitions. It's useful for
* parameter matching, etc.
*/
bool CPPConstType::
is_equivalent(const CPPType &other) const {
const CPPConstType *ot = ((CPPType *)&other)->as_const_type();
if (ot == nullptr) {
return CPPType::is_equivalent(other);
}
return _wrapped_around->is_equivalent(*ot->_wrapped_around);
}
/**
*
*/
void CPPConstType::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
_wrapped_around->output(out, indent_level, scope, complete);
out << " const";
}
/**
* Formats a C++-looking line that defines an instance of the given type, with
* the indicated name. In most cases this will be "type name", but some types
* have special exceptions.
*/
void CPPConstType::
output_instance(std::ostream &out, int indent_level, CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const {
_wrapped_around->output_instance(out, indent_level, scope, complete,
"const " + prename, name);
}
/**
*
*/
CPPDeclaration::SubType CPPConstType::
get_subtype() const {
return ST_const;
}
/**
*
*/
CPPConstType *CPPConstType::
as_const_type() {
return this;
}
/**
* Called by CPPDeclaration() to determine whether this type is equivalent to
* another type of the same type.
*/
bool CPPConstType::
is_equal(const CPPDeclaration *other) const {
const CPPConstType *ot = ((CPPDeclaration *)other)->as_const_type();
assert(ot != nullptr);
return _wrapped_around == ot->_wrapped_around;
}
/**
* Called by CPPDeclaration() to determine whether this type should be ordered
* before another type of the same type, in an arbitrary but fixed ordering.
*/
bool CPPConstType::
is_less(const CPPDeclaration *other) const {
const CPPConstType *ot = ((CPPDeclaration *)other)->as_const_type();
assert(ot != nullptr);
return _wrapped_around < ot->_wrapped_around;
}

View File

@ -1,66 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppConstType.h
* @author drose
* @date 1999-10-28
*/
#ifndef CPPCONSTTYPE_H
#define CPPCONSTTYPE_H
#include "dtoolbase.h"
#include "cppType.h"
/**
*
*/
class CPPConstType : public CPPType {
public:
CPPConstType(CPPType *wrapped_around);
CPPType *_wrapped_around;
virtual bool is_fully_specified() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
virtual CPPType *resolve_type(CPPScope *current_scope,
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_trivially_copyable() 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(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual void output_instance(std::ostream &out, int indent_level,
CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const;
virtual SubType get_subtype() const;
virtual CPPConstType *as_const_type();
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
};
#endif

View File

@ -1,379 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppDeclaration.cxx
* @author drose
* @date 1999-10-19
*/
#include "cppDeclaration.h"
#include "cppPreprocessor.h"
/**
*
*/
CPPDeclaration::
CPPDeclaration(const CPPFile &file, CPPAttributeList attr) :
_file(file),
_attributes(std::move(attr))
{
_vis = V_unknown;
_template_scope = nullptr;
_leading_comment = nullptr;
}
/**
*
*/
CPPDeclaration::
CPPDeclaration(const CPPDeclaration &copy) :
_vis(copy._vis),
_template_scope(copy._template_scope),
_file(copy._file),
_leading_comment(copy._leading_comment),
_attributes(copy._attributes)
{
}
/**
*
*/
CPPDeclaration &CPPDeclaration::
operator = (const CPPDeclaration &copy) {
_vis = copy._vis;
_template_scope = copy._template_scope;
_file = copy._file;
_leading_comment = copy._leading_comment;
_attributes = copy._attributes;
return *this;
}
/**
*
*/
bool CPPDeclaration::
operator == (const CPPDeclaration &other) const {
if (get_subtype() != other.get_subtype()) {
return false;
}
return is_equal(&other);
}
/**
*
*/
bool CPPDeclaration::
operator != (const CPPDeclaration &other) const {
return !(*this == other);
}
/**
*
*/
bool CPPDeclaration::
operator < (const CPPDeclaration &other) const {
if (get_subtype() != other.get_subtype()) {
return get_subtype() < other.get_subtype();
}
return is_less(&other);
}
/**
* Returns true if this is a template declaration of some kind: a template
* function or a template class, typically.
*/
bool CPPDeclaration::
is_template() const {
return _template_scope != nullptr;
}
/**
* If is_template(), above, returns true, this returns the CPPTemplateScope in
* which this particular template declaration is defined. This scope includes
* the information about the template parameters.
*/
CPPTemplateScope *CPPDeclaration::
get_template_scope() const {
return _template_scope;
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which
* has not yet been instantiated.
*/
bool CPPDeclaration::
is_fully_specified() const {
return !is_template();
}
/**
*
*/
CPPDeclaration *CPPDeclaration::
instantiate(const CPPTemplateParameterList *,
CPPScope *, CPPScope *,
CPPPreprocessor *error_sink) const {
if (error_sink != nullptr) {
error_sink->warning("Ignoring template parameters");
}
return (CPPDeclaration *)this;
}
/**
*
*/
CPPDeclaration *CPPDeclaration::
substitute_decl(SubstDecl &subst, CPPScope *, CPPScope *) {
SubstDecl::const_iterator si = subst.find(this);
if (si != subst.end()) {
assert((*si).second != nullptr);
return (*si).second;
}
return this;
}
/**
*
*/
void CPPDeclaration::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
out << _attributes;
}
/**
*
*/
CPPDeclaration::SubType CPPDeclaration::
get_subtype() const {
return ST_empty;
}
/**
*
*/
CPPInstance *CPPDeclaration::
as_instance() {
return nullptr;
}
/**
*
*/
CPPClassTemplateParameter *CPPDeclaration::
as_class_template_parameter() {
return nullptr;
}
/**
*
*/
CPPTypedefType *CPPDeclaration::
as_typedef_type() {
return nullptr;
}
/**
*
*/
CPPTypeDeclaration *CPPDeclaration::
as_type_declaration() {
return nullptr;
}
/**
*
*/
CPPExpression *CPPDeclaration::
as_expression() {
return nullptr;
}
/**
*
*/
CPPType *CPPDeclaration::
as_type() {
return nullptr;
}
/**
*
*/
CPPNamespace *CPPDeclaration::
as_namespace() {
return nullptr;
}
/**
*
*/
CPPUsing *CPPDeclaration::
as_using() {
return nullptr;
}
/**
*
*/
CPPSimpleType *CPPDeclaration::
as_simple_type() {
return nullptr;
}
/**
*
*/
CPPPointerType *CPPDeclaration::
as_pointer_type() {
return nullptr;
}
/**
*
*/
CPPReferenceType *CPPDeclaration::
as_reference_type() {
return nullptr;
}
/**
*
*/
CPPArrayType *CPPDeclaration::
as_array_type() {
return nullptr;
}
/**
*
*/
CPPConstType *CPPDeclaration::
as_const_type() {
return nullptr;
}
/**
*
*/
CPPFunctionType *CPPDeclaration::
as_function_type() {
return nullptr;
}
/**
*
*/
CPPFunctionGroup *CPPDeclaration::
as_function_group() {
return nullptr;
}
/**
*
*/
CPPExtensionType *CPPDeclaration::
as_extension_type() {
return nullptr;
}
/**
*
*/
CPPStructType *CPPDeclaration::
as_struct_type() {
return nullptr;
}
/**
*
*/
CPPEnumType *CPPDeclaration::
as_enum_type() {
return nullptr;
}
/**
*
*/
CPPTBDType *CPPDeclaration::
as_tbd_type() {
return nullptr;
}
/**
*
*/
CPPTypeProxy *CPPDeclaration::
as_type_proxy() {
return nullptr;
}
/**
*
*/
CPPMakeProperty *CPPDeclaration::
as_make_property() {
return nullptr;
}
/**
*
*/
CPPMakeSeq *CPPDeclaration::
as_make_seq() {
return nullptr;
}
/**
*
*/
CPPClosureType *CPPDeclaration::
as_closure_type() {
return nullptr;
}
/**
* Called by CPPDeclaration to determine whether this type is equivalent to
* another type of the same type.
*/
bool CPPDeclaration::
is_equal(const CPPDeclaration *other) const {
return this == other;
}
/**
* Called by CPPDeclaration to determine whether this type should be ordered
* before another type of the same type, in an arbitrary but fixed ordering.
*/
bool CPPDeclaration::
is_less(const CPPDeclaration *other) const {
return this < other;
}
std::ostream &
operator << (std::ostream &out, const CPPDeclaration::SubstDecl &subst) {
CPPDeclaration::SubstDecl::const_iterator it;
for (it = subst.begin(); it != subst.end(); ++it) {
out << " ";
if (it->first == nullptr) {
out << "(null)";
} else {
out << *(it->first);
}
out << " -> ";
if (it->second == nullptr) {
out << "(null)";
} else {
out << *(it->second);
}
out << "\n";
}
return out;
}

View File

@ -1,239 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppDeclaration.h
* @author drose
* @date 1999-10-19
*/
#ifndef CPPDECLARATION_H
#define CPPDECLARATION_H
#include "dtoolbase.h"
#include "cppVisibility.h"
#include "cppFile.h"
#include "cppCommentBlock.h"
#include "cppAttributeList.h"
#include <string>
#include <vector>
#include <map>
#include <set>
class CPPInstance;
class CPPTemplateParameterList;
class CPPTypedefType;
class CPPTypeDeclaration;
class CPPExpression;
class CPPType;
class CPPNamespace;
class CPPUsing;
class CPPSimpleType;
class CPPPointerType;
class CPPReferenceType;
class CPPArrayType;
class CPPConstType;
class CPPFunctionType;
class CPPFunctionGroup;
class CPPExtensionType;
class CPPStructType;
class CPPEnumType;
class CPPTypeProxy;
class CPPMakeProperty;
class CPPMakeSeq;
class CPPClosureType;
class CPPClassTemplateParameter;
class CPPTBDType;
class CPPScope;
class CPPTemplateScope;
class CPPPreprocessor;
/**
*
*/
class CPPDeclaration {
public:
enum SubType {
// Empty declaration
ST_empty,
// Subtypes of CPPDeclaration
ST_instance,
ST_type_declaration,
ST_expression,
ST_type,
ST_namespace,
ST_using,
ST_make_property,
ST_make_seq,
// Subtypes of CPPType
ST_simple,
ST_pointer,
ST_reference,
ST_array,
ST_const,
ST_function,
ST_function_group,
ST_extension,
ST_struct,
ST_enum,
ST_class_template_parameter,
ST_tbd,
ST_type_proxy,
ST_typedef,
ST_closure,
};
CPPDeclaration(const CPPFile &file, CPPAttributeList attr = CPPAttributeList());
CPPDeclaration(const CPPDeclaration &copy);
virtual ~CPPDeclaration() {};
CPPDeclaration &operator = (const CPPDeclaration &copy);
bool operator == (const CPPDeclaration &other) const;
bool operator != (const CPPDeclaration &other) const;
bool operator < (const CPPDeclaration &other) const;
bool is_template() const;
CPPTemplateScope *get_template_scope() const;
virtual bool is_fully_specified() const;
virtual CPPDeclaration *
instantiate(const CPPTemplateParameterList *actual_params,
CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
typedef std::map<CPPDeclaration *, CPPDeclaration *> SubstDecl;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
typedef std::set<CPPDeclaration *> Instantiations;
Instantiations _instantiations;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPInstance *as_instance();
virtual CPPClassTemplateParameter *as_class_template_parameter();
virtual CPPTypedefType *as_typedef_type();
virtual CPPTypeDeclaration *as_type_declaration();
virtual CPPExpression *as_expression();
virtual CPPType *as_type();
virtual CPPNamespace *as_namespace();
virtual CPPUsing *as_using();
virtual CPPSimpleType *as_simple_type();
virtual CPPPointerType *as_pointer_type();
virtual CPPReferenceType *as_reference_type();
virtual CPPArrayType *as_array_type();
virtual CPPConstType *as_const_type();
virtual CPPFunctionType *as_function_type();
virtual CPPFunctionGroup *as_function_group();
virtual CPPExtensionType *as_extension_type();
virtual CPPStructType *as_struct_type();
virtual CPPEnumType *as_enum_type();
virtual CPPTBDType *as_tbd_type();
virtual CPPTypeProxy *as_type_proxy();
virtual CPPMakeProperty *as_make_property();
virtual CPPMakeSeq *as_make_seq();
virtual CPPClosureType *as_closure_type();
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();
}
inline const CPPClosureType *as_closure_type() const {
return ((CPPDeclaration *)this)->as_closure_type();
}
CPPVisibility _vis;
CPPTemplateScope *_template_scope;
CPPFile _file;
CPPCommentBlock *_leading_comment;
CPPAttributeList _attributes;
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
};
inline std::ostream &
operator << (std::ostream &out, const CPPDeclaration &decl) {
decl.output(out, 0, nullptr, false);
return out;
}
std::ostream &
operator << (std::ostream &out, const CPPDeclaration::SubstDecl &decl);
#endif

View File

@ -1,328 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppEnumType.cxx
* @author drose
* @date 1999-10-25
*/
#include "cppEnumType.h"
#include "cppTypedefType.h"
#include "cppExpression.h"
#include "cppSimpleType.h"
#include "cppConstType.h"
#include "cppScope.h"
#include "cppParser.h"
#include "cppIdentifier.h"
#include "indent.h"
/**
* Creates an untyped enum.
*/
CPPEnumType::
CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
CPPScope *scope, const CPPFile &file, CPPAttributeList attr) :
CPPExtensionType(type, ident, current_scope, file, std::move(attr)),
_scope(scope),
_element_type(nullptr),
_last_value(nullptr)
{
_parent_scope = (type == T_enum) ? current_scope : scope;
if (ident != nullptr) {
ident->_native_scope = current_scope;
}
}
/**
* Creates a typed enum.
*/
CPPEnumType::
CPPEnumType(Type type, CPPIdentifier *ident, CPPType *element_type,
CPPScope *current_scope, CPPScope *scope, const CPPFile &file,
CPPAttributeList attr) :
CPPExtensionType(type, ident, current_scope, file, std::move(attr)),
_scope(scope),
_element_type(element_type),
_last_value(nullptr)
{
_parent_scope = (type == T_enum) ? current_scope : scope;
if (ident != nullptr) {
ident->_native_scope = current_scope;
}
}
/**
* Returns true if this is a scoped enum.
*/
bool CPPEnumType::
is_scoped() const {
return (_type != T_enum);
}
/**
* Returns the integral type used to store enum values.
*/
CPPType *CPPEnumType::
get_underlying_type() {
if (_element_type == nullptr) {
// This enum is untyped. Use a suitable default, ie. 'int'. In the
// future, we might want to check whether it fits in an int.
static CPPType *default_element_type = nullptr;
if (default_element_type == nullptr) {
default_element_type =
CPPType::new_type(new CPPConstType(new CPPSimpleType(CPPSimpleType::T_int, 0)));
}
return default_element_type;
} else {
// This enum has an explicit type, so use that.
return CPPType::new_type(new CPPConstType(_element_type));
}
}
/**
*
*/
CPPInstance *CPPEnumType::
add_element(const std::string &name, CPPExpression *value,
CPPPreprocessor *preprocessor, const cppyyltype &pos,
CPPAttributeList attr) {
CPPIdentifier *ident = new CPPIdentifier(name);
ident->_native_scope = _parent_scope;
CPPInstance *inst;
if (_type == T_enum) {
// Weakly typed enum.
inst = new CPPInstance(get_underlying_type(), ident);
} else {
// C++11-style strongly typed enum.
inst = new CPPInstance(this, ident);
}
inst->_storage_class |= CPPInstance::SC_constexpr;
inst->_attributes = std::move(attr);
_elements.push_back(inst);
if (value == nullptr) {
if (_last_value == nullptr) {
// This is the first value, and should therefore be 0.
static CPPExpression *const zero = new CPPExpression(0);
value = zero;
} else if (_last_value->_type == CPPExpression::T_integer) {
value = new CPPExpression(_last_value->_u._integer + 1);
} else if (_last_value->_type == CPPExpression::T_binary_operation &&
_last_value->_u._op._operator == '+' &&
_last_value->_u._op._op2->_type == CPPExpression::T_integer) {
// Prevent an endless expansion of + expressions.
value = new CPPExpression('+',
_last_value->_u._op._op1,
new CPPExpression(_last_value->_u._op._op2->_u._integer + 1));
} else {
// We may not be able to determine the value just yet. No problem;
// we'll just define it as another expression.
static CPPExpression *const one = new CPPExpression(1);
value = new CPPExpression('+', _last_value, one);
}
}
inst->_initializer = value;
_last_value = value;
if (preprocessor != nullptr) {
// Same-line comment?
CPPCommentBlock *comment =
preprocessor->get_comment_on(pos.first_line, pos.file);
if (comment == nullptr) {
// Nope. Check for a comment before this line.
comment =
preprocessor->get_comment_before(pos.first_line, pos.file);
if (comment != nullptr) {
// This is a bit of a hack, but it prevents us from picking up a same-
// line comment from the previous line.
if (comment->_line_number != pos.first_line - 1 ||
comment->_col_number <= pos.first_column) {
inst->_leading_comment = comment;
}
}
} else {
inst->_leading_comment = comment;
}
}
// Add the value to the enum scope (as per C++11), assuming it's not anonymous.
if (_scope != nullptr) {
_scope->add_enum_value(inst);
}
// Now add it to the containing scope as well if it's not an "enum class".
if (!is_scoped() && _parent_scope != nullptr) {
_parent_scope->add_enum_value(inst);
}
return inst;
}
/**
* Returns true if the type has not yet been fully specified, false if it has.
*/
bool CPPEnumType::
is_incomplete() const {
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
* has not yet been instantiated.
*/
bool CPPEnumType::
is_fully_specified() const {
if (!CPPDeclaration::is_fully_specified()) {
return false;
}
if (_ident != nullptr && !_ident->is_fully_specified()) {
return false;
}
if (_element_type != nullptr && !_element_type->is_fully_specified()) {
return false;
}
Elements::const_iterator ei;
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
if (!(*ei)->is_fully_specified()) {
return false;
}
}
return true;
}
/**
*
*/
CPPDeclaration *CPPEnumType::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
SubstDecl::const_iterator si = subst.find(this);
if (si != subst.end()) {
return (*si).second;
}
CPPEnumType *rep = new CPPEnumType(*this);
if (_ident != nullptr) {
rep->_ident =
_ident->substitute_decl(subst, current_scope, global_scope);
}
if (_element_type != nullptr) {
rep->_element_type =
_element_type->substitute_decl(subst, current_scope, global_scope)
->as_type();
}
bool any_changed = false;
for (size_t i = 0; i < _elements.size(); ++i) {
// We don't just do substitute_decl on the instance, which could lead to
// an infinite recursion.
CPPInstance *element = _elements[i];
CPPExpression *value = element->_initializer->
substitute_decl(subst, current_scope, global_scope)->as_expression();
if (is_scoped()) {
// For a strong enum, we consider the elements to be of this type.
if (value != element->_initializer) {
rep->_elements[i] = new CPPInstance(rep, element->_ident);
rep->_elements[i]->_initializer = value;
any_changed = true;
}
} else if (value != element->_initializer ||
rep->get_underlying_type() != get_underlying_type()) {
// In an unscoped enum, the elements are integers.
rep->_elements[i] = new CPPInstance(rep->get_underlying_type(), element->_ident);
rep->_elements[i]->_initializer = value;
any_changed = true;
}
}
if (rep->_ident == _ident &&
rep->_element_type == _element_type &&
!any_changed) {
delete rep;
rep = this;
}
rep = CPPType::new_type(rep)->as_enum_type();
subst.insert(SubstDecl::value_type(this, rep));
return rep;
}
/**
*
*/
void CPPEnumType::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
if (!complete && _ident != nullptr) {
// If we have a name, use it.
if (cppparser_output_class_keyword) {
out << _type << " ";
}
out << _ident->get_local_name(scope);
}
else {
out << _type;
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
if (_ident != nullptr) {
out << " " << _ident->get_local_name(scope);
}
if (_element_type != nullptr) {
out << " : " << _element_type->get_local_name(scope);
}
out << " {\n";
for (CPPInstance *element : _elements) {
indent(out, indent_level + 2) << element->get_local_name();
if (!element->_attributes.is_empty()) {
out << " " << element->_attributes;
}
if (element->_initializer != nullptr) {
out << " = " << *element->_initializer;
}
out << ",\n";
}
indent(out, indent_level) << "}";
}
}
/**
*
*/
CPPDeclaration::SubType CPPEnumType::
get_subtype() const {
return ST_enum;
}
/**
*
*/
CPPEnumType *CPPEnumType::
as_enum_type() {
return this;
}

View File

@ -1,71 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppEnumType.h
* @author drose
* @date 1999-10-25
*/
#ifndef CPPENUMTYPE_H
#define CPPENUMTYPE_H
#include "dtoolbase.h"
#include "cppBisonDefs.h"
#include "cppExtensionType.h"
#include <vector>
class CPPExpression;
class CPPInstance;
class CPPScope;
/**
*
*/
class CPPEnumType : public CPPExtensionType {
public:
CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
CPPScope *scope, const CPPFile &file,
CPPAttributeList attr = CPPAttributeList());
CPPEnumType(Type type, CPPIdentifier *ident, CPPType *element_type,
CPPScope *current_scope, CPPScope *scope, const CPPFile &file,
CPPAttributeList attr = CPPAttributeList());
bool is_scoped() const;
CPPType *get_underlying_type();
CPPInstance *add_element(const std::string &name, CPPExpression *value,
CPPPreprocessor *preprocessor, const cppyyltype &pos,
CPPAttributeList attr = CPPAttributeList());
virtual bool is_incomplete() const;
virtual bool is_fully_specified() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPEnumType *as_enum_type();
CPPScope *_parent_scope;
CPPScope *_scope;
CPPType *_element_type;
typedef std::vector<CPPInstance *> Elements;
Elements _elements;
CPPExpression *_last_value;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,203 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppExpression.h
* @author drose
* @date 1999-10-25
*/
#ifndef CPPEXPRESSION_H
#define CPPEXPRESSION_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
class CPPIdentifier;
class CPPType;
class CPPPreprocessor;
class CPPFunctionGroup;
/**
*
*/
class CPPExpression : public CPPDeclaration {
public:
enum Type {
T_nullptr,
T_boolean,
T_integer,
T_real,
T_string,
T_wstring,
T_u8string,
T_u16string,
T_u32string,
T_variable,
T_function,
T_unknown_ident,
T_typecast,
T_static_cast,
T_dynamic_cast,
T_const_cast,
T_reinterpret_cast,
T_construct,
T_default_construct,
T_aggregate_init,
T_empty_aggregate_init,
T_new,
T_default_new,
T_sizeof_type,
T_sizeof_expr,
T_sizeof_ellipsis,
T_alignof,
T_unary_operation,
T_binary_operation,
T_trinary_operation,
T_literal,
T_raw_literal,
T_typeid_type,
T_typeid_expr,
T_type_trait,
T_lambda,
// These are used when parsing =default and =delete methods.
T_default,
T_delete,
};
CPPExpression(bool value);
CPPExpression(unsigned long long value);
CPPExpression(int value);
CPPExpression(const std::string &value);
CPPExpression(long double value);
CPPExpression(CPPIdentifier *ident, CPPScope *current_scope,
CPPScope *global_scope, CPPPreprocessor *error_sink = nullptr);
CPPExpression(int unary_operator, CPPExpression *op1);
CPPExpression(int binary_operator, CPPExpression *op1, CPPExpression *op2);
CPPExpression(int trinary_operator, CPPExpression *op1, CPPExpression *op2, CPPExpression *op3);
static CPPExpression typecast_op(CPPType *type, CPPExpression *op1, Type cast_type = T_typecast);
static CPPExpression construct_op(CPPType *type, CPPExpression *op1);
static CPPExpression aggregate_init_op(CPPType *type, CPPExpression *op1);
static CPPExpression new_op(CPPType *type, CPPExpression *op1 = nullptr);
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 = nullptr);
static CPPExpression sizeof_func(CPPType *type);
static CPPExpression sizeof_func(CPPExpression *op1);
static CPPExpression sizeof_ellipsis_func(CPPIdentifier *ident);
static CPPExpression alignof_func(CPPType *type);
static CPPExpression lambda(CPPClosureType *type);
static CPPExpression literal(unsigned long long value, CPPInstance *lit_op);
static CPPExpression literal(long double value, CPPInstance *lit_op);
static CPPExpression literal(CPPExpression *value, CPPInstance *lit_op);
static CPPExpression raw_literal(const std::string &raw, CPPInstance *lit_op);
static const CPPExpression &get_nullptr();
static const CPPExpression &get_default();
static const CPPExpression &get_delete();
enum ResultType {
RT_integer,
RT_real,
RT_pointer,
RT_error
};
class Result {
public:
Result();
Result(int value);
Result(double value);
Result(void *value);
int as_integer() const;
double as_real() const;
void *as_pointer() const;
bool as_boolean() const;
void output(std::ostream &out) const;
ResultType _type;
union {
int _integer;
double _real;
void *_pointer;
} _u;
};
Result evaluate() const;
CPPType *determine_type() const;
bool is_lvalue() const;
bool is_tbd() const;
virtual bool is_fully_specified() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPExpression *as_expression();
Type _type;
std::string _str;
union {
bool _boolean;
unsigned long long _integer;
long double _real;
CPPInstance *_variable;
CPPFunctionGroup *_fgroup;
CPPIdentifier *_ident;
CPPClosureType *_closure_type;
struct {
union {
CPPType *_type;
CPPExpression *_expr;
};
CPPType *_std_type_info;
} _typeid;
struct {
CPPType *_to;
CPPExpression *_op1;
} _typecast;
struct {
// One of the yytoken values: a character, or something like EQCOMPARE.
int _operator;
CPPExpression *_op1;
CPPExpression *_op2;
CPPExpression *_op3;
} _op;
struct {
CPPInstance *_operator;
CPPExpression *_value;
} _literal;
struct {
int _trait;
CPPType *_type;
CPPType *_arg;
} _type_trait;
} _u;
protected:
static CPPType *elevate_type(CPPType *t1, CPPType *t2);
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
};
inline std::ostream &
operator << (std::ostream &out, const CPPExpression::Result &result) {
result.output(out);
return out;
}
#endif

View File

@ -1,77 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppExpressionParser.cxx
* @author drose
* @date 1999-10-25
*/
#include "cppExpressionParser.h"
#include "cppExpression.h"
/**
*
*/
CPPExpressionParser::
CPPExpressionParser(CPPScope *current_scope, CPPScope *global_scope) :
_current_scope(current_scope),
_global_scope(global_scope)
{
_expr = nullptr;
}
/**
*
*/
CPPExpressionParser::
~CPPExpressionParser() {
}
/**
*
*/
bool CPPExpressionParser::
parse_expr(const std::string &expr) {
if (!init_const_expr(expr)) {
std::cerr << "Unable to parse expression\n";
return false;
}
_expr = parse_const_expr(this, _current_scope, _global_scope);
return get_error_count() == 0;
}
/**
*
*/
bool CPPExpressionParser::
parse_expr(const std::string &expr, const CPPPreprocessor &filepos) {
if (!init_const_expr(expr)) {
std::cerr << "Unable to parse expression\n";
return false;
}
copy_filepos(filepos);
_expr = parse_const_expr(this, _current_scope, _global_scope);
return get_error_count() == 0;
}
/**
*
*/
void CPPExpressionParser::
output(std::ostream &out) const {
if (_expr == nullptr) {
out << "(null expr)";
} else {
out << *_expr;
}
}

View File

@ -1,48 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppExpressionParser.h
* @author drose
* @date 1999-10-25
*/
#ifndef CPPEXPRESSIONPARSER_H
#define CPPEXPRESSIONPARSER_H
#include "dtoolbase.h"
#include "cppPreprocessor.h"
class CPPExpression;
class CPPScope;
/**
*
*/
class CPPExpressionParser : public CPPPreprocessor {
public:
CPPExpressionParser(CPPScope *current_scope, CPPScope *global_scope);
~CPPExpressionParser();
bool parse_expr(const std::string &expr);
bool parse_expr(const std::string &expr, const CPPPreprocessor &filepos);
void output(std::ostream &out) const;
CPPScope *_current_scope;
CPPScope *_global_scope;
CPPExpression *_expr;
};
inline std::ostream &
operator << (std::ostream &out, const CPPExpressionParser &ep) {
ep.output(out);
return out;
}
#endif

View File

@ -1,281 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppExtensionType.cxx
* @author drose
* @date 1999-10-21
*/
#include "cppExtensionType.h"
#include "cppTypedefType.h"
#include "cppIdentifier.h"
#include "cppParser.h"
#include "indent.h"
/**
*
*/
CPPExtensionType::
CPPExtensionType(CPPExtensionType::Type type,
CPPIdentifier *ident, CPPScope *current_scope,
const CPPFile &file, CPPAttributeList attr) :
CPPType(file),
_type(type), _ident(ident),
_alignment(nullptr)
{
if (_ident != nullptr) {
_ident->_native_scope = current_scope;
}
_attributes = std::move(attr);
}
/**
*
*/
std::string CPPExtensionType::
get_simple_name() const {
if (_ident == nullptr) {
return "";
}
return _ident->get_simple_name();
}
/**
*
*/
std::string CPPExtensionType::
get_local_name(CPPScope *scope) const {
if (_ident == nullptr) {
return "";
}
return _ident->get_local_name(scope);
}
/**
*
*/
std::string CPPExtensionType::
get_fully_scoped_name() const {
if (_ident == nullptr) {
return "";
}
return _ident->get_fully_scoped_name();
}
/**
* Returns true if the type has not yet been fully specified, false if it has.
*/
bool CPPExtensionType::
is_incomplete() const {
return true;
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPExtensionType::
is_tbd() const {
if (_ident != nullptr) {
return _ident->is_tbd();
}
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 || _type == T_enum_class || _type == T_enum_struct);
}
/**
* Returns true if the type can be safely copied by memcpy or memmove.
*/
bool CPPExtensionType::
is_trivially_copyable() const {
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 != nullptr && is_equal(other);
}
return false;
}
/**
* Returns true if the type is default-constructible.
*/
bool CPPExtensionType::
is_default_constructible() const {
return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
}
/**
* Returns true if the type is copy-constructible.
*/
bool CPPExtensionType::
is_copy_constructible() const {
return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
}
/**
* Returns true if the type is copy-assignable.
*/
bool CPPExtensionType::
is_copy_assignable() const {
return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
}
/**
*
*/
CPPDeclaration *CPPExtensionType::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
SubstDecl::const_iterator si = subst.find(this);
if (si != subst.end()) {
return (*si).second;
}
CPPExtensionType *rep = new CPPExtensionType(*this);
if (_ident != nullptr) {
rep->_ident =
_ident->substitute_decl(subst, current_scope, global_scope);
}
if (rep->_ident == _ident) {
delete rep;
rep = this;
}
rep = CPPType::new_type(rep)->as_extension_type();
subst.insert(SubstDecl::value_type(this, rep));
return rep;
}
/**
* If this CPPType object is a forward reference or other nonspecified
* reference to a type that might now be known a real type, returns the real
* type. Otherwise returns the type itself.
*/
CPPType *CPPExtensionType::
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
if (_ident == nullptr) {
// We can't resolve anonymous types. But that's OK, since they can't be
// forward declared anyway.
return this;
}
// Maybe it has been defined by now.
CPPType *type = _ident->find_type(current_scope, global_scope);
if (type != nullptr) {
return type;
}
return this;
}
/**
* 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
* different pointers or somewhat different definitions. It's useful for
* parameter matching, etc.
*/
bool CPPExtensionType::
is_equivalent(const CPPType &other) const {
const CPPExtensionType *ot = ((CPPType *)&other)->as_extension_type();
if (ot == nullptr) {
return CPPType::is_equivalent(other);
}
// We consider two different extension types to be equivalent if they have
// the same name.
return _ident != nullptr && ot->_ident != nullptr && *_ident == *ot->_ident;
}
/**
*
*/
void CPPExtensionType::
output(std::ostream &out, int, CPPScope *scope, bool complete) const {
if (_ident != nullptr) {
// If we have a name, use it.
if (complete || cppparser_output_class_keyword) {
out << _type << " ";
}
if (complete && !_attributes.is_empty()) {
out << _attributes << " ";
}
out << _ident->get_local_name(scope);
} else if (!_typedefs.empty()) {
// If we have a typedef name, use it.
out << _typedefs.front()->get_local_name(scope);
} else {
out << "(**unknown forward-reference type**)";
}
}
/**
*
*/
CPPDeclaration::SubType CPPExtensionType::
get_subtype() const {
return ST_extension;
}
/**
*
*/
CPPExtensionType *CPPExtensionType::
as_extension_type() {
return this;
}
std::ostream &
operator << (std::ostream &out, CPPExtensionType::Type type) {
switch (type) {
case CPPExtensionType::T_enum:
return out << "enum";
case CPPExtensionType::T_class:
return out << "class";
case CPPExtensionType::T_struct:
return out << "struct";
case CPPExtensionType::T_union:
return out << "union";
case CPPExtensionType::T_enum_class:
return out << "enum class";
case CPPExtensionType::T_enum_struct:
return out << "enum struct";
default:
return out << "***invalid extension type***";
}
}

View File

@ -1,81 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppExtensionType.h
* @author drose
* @date 1999-10-21
*/
#ifndef CPPEXTENSIONTYPE_H
#define CPPEXTENSIONTYPE_H
#include "dtoolbase.h"
#include "cppType.h"
#include "cppInstance.h"
class CPPScope;
class CPPIdentifier;
/**
* Base class of enum, class, struct, and union types. An instance of the
* base class (instead of one of the specializations) is used for forward
* references.
*/
class CPPExtensionType : public CPPType {
public:
enum Type {
T_enum,
T_class,
T_struct,
T_union,
T_enum_class,
T_enum_struct,
};
CPPExtensionType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
const CPPFile &file, CPPAttributeList attr = CPPAttributeList());
virtual std::string get_simple_name() const;
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
virtual std::string get_fully_scoped_name() const;
virtual bool is_incomplete() const;
virtual bool is_tbd() const;
virtual bool is_standard_layout() const;
virtual bool is_trivial() const;
virtual bool is_trivially_copyable() const;
virtual bool is_constructible(const CPPType *type) const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_copy_assignable() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
virtual CPPType *resolve_type(CPPScope *current_scope,
CPPScope *global_scope);
virtual bool is_equivalent(const CPPType &other) const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPExtensionType *as_extension_type();
Type _type;
CPPIdentifier *_ident;
CPPExpression *_alignment;
};
std::ostream &operator << (std::ostream &out, CPPExtensionType::Type type);
#endif

View File

@ -1,144 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppFile.cxx
* @author drose
* @date 1999-11-11
*/
#include "cppFile.h"
#include <ctype.h>
using std::string;
/**
*
*/
CPPFile::
CPPFile(const Filename &filename, const Filename &filename_as_referenced,
Source source) :
_filename(filename), _filename_as_referenced(filename_as_referenced),
_source(source),
_pragma_once(false)
{
_filename.set_text();
_filename_as_referenced.set_text();
}
/**
* Returns true if the file appears to be a C or C++ source code file based on
* its extension. That is, returns true if the filename ends in .c, .C, .cc,
* .cpp, or any of a series of likely extensions.
*/
bool CPPFile::
is_c_or_i_file() const {
return is_c_or_i_file(_filename);
}
/**
* Returns true if the file appears to be a C or C++ source code file based on
* its extension. That is, returns true if the filename ends in .c, .C, .cc,
* .cpp, or any of a series of likely extensions.
*/
bool CPPFile::
is_c_or_i_file(const Filename &filename) {
string extension = filename.get_extension();
// downcase the extension.
for (string::iterator ei = extension.begin();
ei != extension.end();
++ei) {
(*ei) = tolower(*ei);
}
return (extension == "c" || extension == "cc" ||
extension == "cpp" || extension == "c++" || extension == "cxx" ||
extension == "i" || extension == "t");
}
/**
* Returns true if the file appears to be a C or C++ source code file based on
* its extension. That is, returns true if the filename ends in .c, .C, .cc,
* .cpp, or any of a series of likely extensions.
*/
bool CPPFile::
is_c_file() const {
return is_c_file(_filename);
}
/**
* Returns true if the file appears to be a C or C++ source code file based on
* its extension. That is, returns true if the filename ends in .c, .C, .cc,
* .cpp, or any of a series of likely extensions.
*/
bool CPPFile::
is_c_file(const Filename &filename) {
string extension = filename.get_extension();
// downcase the extension.
for (string::iterator ei = extension.begin();
ei != extension.end();
++ei) {
(*ei) = tolower(*ei);
}
return (extension == "c" || extension == "cc" ||
extension == "cpp" || extension == "c++" || extension == "cxx");
}
/**
* If the other file is "nearer" than this file (in the sense that a file in
* the local directory is nearer than a file in the system directory, etc.),
* replaces this file's information with that of the other. Otherwise, does
* nothing.
*/
void CPPFile::
replace_nearer(const CPPFile &other) {
if ((int)_source > (int)other._source) {
(*this) = other;
}
}
/**
*
*/
bool CPPFile::
operator < (const CPPFile &other) const {
return _filename < other._filename;
}
/**
*
*/
bool CPPFile::
operator == (const CPPFile &other) const {
return _filename == other._filename;
}
/**
*
*/
bool CPPFile::
operator != (const CPPFile &other) const {
return _filename != other._filename;
}
/**
*
*/
const char *CPPFile::
c_str() const {
return _filename.c_str();
}
/**
*
*/
bool CPPFile::
empty() const {
return _filename.empty();
}

View File

@ -1,63 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppFile.h
* @author drose
* @date 1999-11-11
*/
#ifndef CPPFILE_H
#define CPPFILE_H
#include "dtoolbase.h"
#include "filename.h"
/**
* This defines a source file (typically a C++ header file) that is parsed by
* the CPPParser. Each declaration indicates the source file where it
* appeared.
*/
class CPPFile {
public:
enum Source {
S_local, // File resides in the current directory
S_alternate, // File resides in some other directory
S_system, // File resides in a system directory
S_none, // File is internally generated
};
CPPFile(const Filename &filename = "",
const Filename &filename_as_referenced = "",
Source source = S_none);
bool is_c_or_i_file() const;
static bool is_c_or_i_file(const Filename &filename);
bool is_c_file() const;
static bool is_c_file(const Filename &filename);
void replace_nearer(const CPPFile &other);
bool operator < (const CPPFile &other) const;
bool operator == (const CPPFile &other) const;
bool operator != (const CPPFile &other) const;
const char *c_str() const;
bool empty() const;
Filename _filename;
Filename _filename_as_referenced;
mutable Source _source;
mutable bool _pragma_once;
};
inline std::ostream &operator << (std::ostream &out, const CPPFile &file) {
return out << file._filename;
}
#endif

View File

@ -1,92 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppFunctionGroup.cxx
* @author drose
* @date 1999-11-11
*/
#include "cppFunctionGroup.h"
#include "cppFunctionType.h"
#include "cppInstance.h"
#include "indent.h"
/**
*
*/
CPPFunctionGroup::
CPPFunctionGroup(const std::string &name) :
CPPDeclaration(CPPFile()),
_name(name)
{
}
/**
*
*/
CPPFunctionGroup::
~CPPFunctionGroup() {
}
/**
* If all the functions that share this name have the same return type,
* returns that type. Otherwise, if some functions have different return
* types, returns NULL.
*/
CPPType *CPPFunctionGroup::
get_return_type() const {
CPPType *return_type = nullptr;
if (!_instances.empty()) {
Instances::const_iterator ii = _instances.begin();
return_type = (*ii)->_type->as_function_type()->_return_type;
++ii;
while (ii != _instances.end()) {
if ((*ii)->_type->as_function_type()->_return_type != return_type) {
return nullptr;
}
++ii;
}
}
return return_type;
}
/**
*
*/
void CPPFunctionGroup::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
if (!_instances.empty()) {
Instances::const_iterator ii = _instances.begin();
(*ii)->output(out, indent_level, scope, complete);
++ii;
while (ii != _instances.end()) {
out << ";\n";
indent(out, indent_level);
(*ii)->output(out, indent_level, scope, complete);
++ii;
}
}
}
/**
*
*/
CPPDeclaration::SubType CPPFunctionGroup::
get_subtype() const {
return ST_function_group;
}
/**
*
*/
CPPFunctionGroup *CPPFunctionGroup::
as_function_group() {
return this;
}

View File

@ -1,47 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppFunctionGroup.h
* @author drose
* @date 1999-11-11
*/
#ifndef CPPFUNCTIONGROUP_H
#define CPPFUNCTIONGROUP_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
class CPPInstance;
/**
* This class is simply a container for one or more CPPInstances for functions
* of the same name. It's handy for storing in the CPPScope, so that
* CPPScope::find_symbol() can return a single pointer to indicate all of the
* functions that may share a given name.
*/
class CPPFunctionGroup : public CPPDeclaration {
public:
CPPFunctionGroup(const std::string &name);
~CPPFunctionGroup();
CPPType *get_return_type() const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPFunctionGroup *as_function_group();
typedef std::vector<CPPInstance *> Instances;
Instances _instances;
std::string _name;
};
#endif

View File

@ -1,463 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppFunctionType.cxx
* @author drose
* @date 1999-10-21
*/
#include "cppFunctionType.h"
#include "cppParameterList.h"
#include "cppSimpleType.h"
#include "cppInstance.h"
using std::ostream;
using std::ostringstream;
using std::string;
/**
*
*/
CPPFunctionType::
CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
int flags) :
CPPType(CPPFile()),
_return_type(return_type),
_parameters(parameters),
_flags(flags)
{
_class_owner = nullptr;
// If the parameter list contains just the token "void", it means no
// parameters.
if (_parameters != nullptr &&
_parameters->_parameters.size() == 1 &&
_parameters->_parameters.front()->_type->as_simple_type() != nullptr &&
_parameters->_parameters.front()->_type->as_simple_type()->_type ==
CPPSimpleType::T_void &&
_parameters->_parameters.front()->_ident == nullptr) {
_parameters->_parameters.clear();
}
}
/**
*
*/
CPPFunctionType::
CPPFunctionType(const CPPFunctionType &copy) :
CPPType(copy),
_return_type(copy._return_type),
_parameters(copy._parameters),
_flags(copy._flags),
_class_owner(copy._class_owner)
{
}
/**
*
*/
void CPPFunctionType::
operator = (const CPPFunctionType &copy) {
CPPType::operator = (copy);
_return_type = copy._return_type;
_parameters = copy._parameters;
_flags = copy._flags;
_class_owner = copy._class_owner;
}
/**
* Returns true if the function accepts the given number of parameters.
*/
bool CPPFunctionType::
accepts_num_parameters(int num_parameters) {
assert(num_parameters >= 0);
if (_parameters == nullptr) {
return (num_parameters == 0);
}
size_t actual_num_parameters = _parameters->_parameters.size();
// If we passed too many parameters, it must have an ellipsis.
if ((size_t)num_parameters > actual_num_parameters) {
return _parameters->_includes_ellipsis;
}
// Make sure all superfluous parameters have a default value.
for (size_t i = (size_t)num_parameters; i < actual_num_parameters; ++i) {
CPPInstance *param = _parameters->_parameters[i];
if (param->_initializer == nullptr) {
return false;
}
}
return true;
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which
* has not yet been instantiated.
*/
bool CPPFunctionType::
is_fully_specified() const {
return CPPType::is_fully_specified() &&
_return_type->is_fully_specified() &&
_parameters->is_fully_specified();
}
/**
*
*/
CPPDeclaration *CPPFunctionType::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
SubstDecl::const_iterator si = subst.find(this);
if (si != subst.end()) {
return (*si).second;
}
CPPFunctionType *rep = new CPPFunctionType(*this);
if (_return_type != nullptr) {
rep->_return_type =
_return_type->substitute_decl(subst, current_scope, global_scope)
->as_type();
}
if (_parameters != nullptr) {
rep->_parameters =
_parameters->substitute_decl(subst, current_scope, global_scope);
}
if (rep->_return_type == _return_type &&
rep->_parameters == _parameters) {
delete rep;
rep = this;
}
rep = CPPType::new_type(rep)->as_function_type();
subst.insert(SubstDecl::value_type(this, rep));
return rep;
}
/**
* If this CPPType object is a forward reference or other nonspecified
* reference to a type that might now be known a real type, returns the real
* type. Otherwise returns the type itself.
*/
CPPType *CPPFunctionType::
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
CPPType *rtype = _return_type->resolve_type(current_scope, global_scope);
CPPParameterList *params;
if (_parameters == nullptr) {
params = nullptr;
} else {
params = _parameters->resolve_type(current_scope, global_scope);
}
if (rtype != _return_type || params != _parameters) {
CPPFunctionType *rep = new CPPFunctionType(*this);
rep->_return_type = rtype;
rep->_parameters = params;
return CPPType::new_type(rep);
}
return this;
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPFunctionType::
is_tbd() const {
if (_return_type->is_tbd()) {
return true;
}
return _parameters == nullptr || _parameters->is_tbd();
}
/**
* Returns true if the type is considered a Plain Old Data (POD) type.
*/
bool CPPFunctionType::
is_trivial() const {
return false;
}
/**
* Returns true if the type can be safely copied by memcpy or memmove.
*/
bool CPPFunctionType::
is_trivially_copyable() const {
return false;
}
/**
*
*/
void CPPFunctionType::
output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
output(out, indent_level, scope, complete, -1);
}
/**
* The additional parameter allows us to specify the number of parameters we
* wish to show the default values for. If num_default_parameters is >= 0, it
* indicates the number of default parameter values to show on output.
* Otherwise, all parameter values are shown.
*/
void CPPFunctionType::
output(ostream &out, int indent_level, CPPScope *scope, bool complete,
int num_default_parameters) const {
if (_flags & F_trailing_return_type) {
// It was declared using trailing return type, so let's format it that
// way.
out << "auto(";
_parameters->output(out, scope, true, num_default_parameters);
out << ")";
if (_flags & F_const_method) {
out << " const";
}
if (_flags & F_noexcept) {
out << " noexcept";
}
if (_flags & F_final) {
out << " final";
}
if (_flags & F_override) {
out << " override";
}
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
out << " -> ";
_return_type->output(out, indent_level, scope, false);
}
else {
_return_type->output(out, indent_level, scope, complete);
out << "(";
_parameters->output(out, scope, true, num_default_parameters);
out << ")";
if (_flags & F_const_method) {
out << " const";
}
if (_flags & F_noexcept) {
out << " noexcept";
}
if (_flags & F_final) {
out << " final";
}
if (_flags & F_override) {
out << " override";
}
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
}
}
/**
* Formats a C++-looking line that defines an instance of the given type, with
* the indicated name. In most cases this will be "type name", but some types
* have special exceptions.
*/
void CPPFunctionType::
output_instance(ostream &out, int indent_level, CPPScope *scope,
bool complete, const string &prename,
const string &name) const {
output_instance(out, indent_level, scope, complete, prename, name, -1);
}
/**
* The additional parameter allows us to specify the number of parameters we
* wish to show the default values for. If num_default_parameters is >= 0, it
* indicates the number of default parameter values to show on output.
* Otherwise, all parameter values are shown.
*/
void CPPFunctionType::
output_instance(ostream &out, int indent_level, CPPScope *scope,
bool complete, const string &prename,
const string &name, int num_default_parameters) const {
ostringstream parm_string;
parm_string << "(";
_parameters->output(parm_string, scope, true, num_default_parameters);
parm_string << ")";
string str = parm_string.str();
if (_flags & (F_constructor | F_destructor)) {
// No return type for constructors and destructors.
out << prename << name << str;
}
else if (_flags & F_trailing_return_type) {
// It was declared using trailing return type, so let's format it that
// way.
out << "auto ";
if (prename.empty()) {
out << name;
} else {
out << "(" << prename << name << ")";
}
out << str;
}
else if (_flags & F_operator_typecast) {
out << "operator ";
_return_type->output_instance(out, indent_level, scope, complete,
"", prename + str);
}
else {
if (prename.empty()) {
_return_type->output_instance(out, indent_level, scope, complete,
"", prename + name + str);
} else {
_return_type->output_instance(out, indent_level, scope, complete,
"", "(" + prename + name + ")" + str);
}
}
if (_flags & F_const_method) {
out << " const";
}
if (_flags & F_volatile_method) {
out << " volatile";
}
if (_flags & F_noexcept) {
out << " noexcept";
}
if (_flags & F_final) {
out << " final";
}
if (_flags & F_override) {
out << " override";
}
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
if (_flags & F_trailing_return_type) {
out << " -> ";
_return_type->output(out, indent_level, scope, false);
}
}
/**
* Returns the number of parameters in the list that may take default values.
*/
int CPPFunctionType::
get_num_default_parameters() const {
// The trick is just to count, beginning from the end and working towards
// the front, the number of parameters that have some initializer.
if (_parameters == nullptr) {
return 0;
}
const CPPParameterList::Parameters &params = _parameters->_parameters;
CPPParameterList::Parameters::const_reverse_iterator pi;
int count = 0;
for (pi = params.rbegin();
pi != params.rend() && (*pi)->_initializer != nullptr;
++pi) {
count++;
}
return count;
}
/**
*
*/
CPPDeclaration::SubType CPPFunctionType::
get_subtype() const {
return ST_function;
}
/**
*
*/
CPPFunctionType *CPPFunctionType::
as_function_type() {
return this;
}
/**
* This is similar to is_equal(), except it is more forgiving: it considers
* the functions to be equivalent only if the return type and the types of all
* parameters match.
*
* Note that this isn't symmetric to account for covariant return types.
*/
bool CPPFunctionType::
match_virtual_override(const CPPFunctionType &other) const {
if (!_return_type->is_equivalent(*other._return_type) &&
!_return_type->is_convertible_to(other._return_type)) {
return false;
}
if (((_flags ^ other._flags) & ~(F_override | F_final)) != 0) {
return false;
}
if (!_parameters->is_equivalent(*other._parameters)) {
return false;
}
return true;
}
/**
* Called by CPPDeclaration() to determine whether this type is equivalent to
* another type of the same type.
*/
bool CPPFunctionType::
is_equal(const CPPDeclaration *other) const {
const CPPFunctionType *ot = ((CPPDeclaration *)other)->as_function_type();
assert(ot != nullptr);
if (_return_type != ot->_return_type) {
return false;
}
if (_flags != ot->_flags) {
return false;
}
if (_parameters == ot->_parameters) {
return true;
}
if (_parameters == nullptr || ot->_parameters == nullptr ||
*_parameters != *ot->_parameters) {
return false;
}
return true;
}
/**
* Called by CPPDeclaration() to determine whether this type should be ordered
* before another type of the same type, in an arbitrary but fixed ordering.
*/
bool CPPFunctionType::
is_less(const CPPDeclaration *other) const {
const CPPFunctionType *ot = ((CPPDeclaration *)other)->as_function_type();
assert(ot != nullptr);
if (_return_type != ot->_return_type) {
return _return_type < ot->_return_type;
}
if (_flags != ot->_flags) {
return _flags < ot->_flags;
}
if (_parameters == ot->_parameters) {
return 0;
}
if (_parameters == nullptr || ot->_parameters == nullptr) {
return _parameters < ot->_parameters;
}
return *_parameters < *ot->_parameters;
}

View File

@ -1,101 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppFunctionType.h
* @author drose
* @date 1999-10-21
*/
#ifndef CPPFUNCTIONTYPE_H
#define CPPFUNCTIONTYPE_H
#include "dtoolbase.h"
#include "cppType.h"
class CPPParameterList;
class CPPIdentifier;
/**
*
*/
class CPPFunctionType : public CPPType {
public:
enum Flags {
F_const_method = 0x001,
F_operator_typecast = 0x002,
F_constructor = 0x004,
F_destructor = 0x008,
F_method_pointer = 0x010,
F_unary_op = 0x020,
F_operator = 0x040,
F_noexcept = 0x080,
F_copy_constructor = 0x200,
F_move_constructor = 0x400,
F_trailing_return_type = 0x800,
F_final = 0x1000,
F_override = 0x2000,
F_volatile_method = 0x4000,
F_lvalue_method = 0x8000,
F_rvalue_method = 0x10000,
F_copy_assignment_operator = 0x20000,
F_move_assignment_operator = 0x40000,
};
CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
int flags);
CPPFunctionType(const CPPFunctionType &copy);
void operator = (const CPPFunctionType &copy);
bool accepts_num_parameters(int num_parameters);
CPPType *_return_type;
CPPParameterList *_parameters;
int _flags;
virtual bool is_fully_specified() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
virtual CPPType *resolve_type(CPPScope *current_scope,
CPPScope *global_scope);
virtual bool is_tbd() const;
virtual bool is_trivial() const;
virtual bool is_trivially_copyable() const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete, int num_default_parameters) const;
virtual void output_instance(std::ostream &out, int indent_level,
CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const;
void output_instance(std::ostream &out, int indent_level,
CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name,
int num_default_parameters) const;
int get_num_default_parameters() const;
virtual SubType get_subtype() const;
virtual CPPFunctionType *as_function_type();
bool match_virtual_override(const CPPFunctionType &other) const;
CPPIdentifier *_class_owner;
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
};
#endif

View File

@ -1,16 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppGlobals.cxx
* @author drose
* @date 2000-05-16
*/
#include "cppGlobals.h"
std::string cpp_longlong_keyword;

View File

@ -1,26 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppGlobals.h
* @author drose
* @date 2000-05-16
*/
#ifndef CPPGLOBALS_H
#define CPPGLOBALS_H
#include "dtoolbase.h"
// Some compilers (notably VC++) define a special keyword to represent a
// 64-bit integer, but don't recognize "long long int". To parse (and
// generate) code for these compilers, set this string to the 64-bit integer
// typename keyword.
extern std::string cpp_longlong_keyword;
#endif

View File

@ -1,612 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppIdentifier.cxx
* @author drose
* @date 1999-10-26
*/
#include "cppIdentifier.h"
#include "cppScope.h"
#include "cppTemplateScope.h"
#include "cppPreprocessor.h"
#include "cppTemplateParameterList.h"
#include "cppTBDType.h"
#include "cppStructType.h"
using std::string;
/**
*
*/
CPPIdentifier::
CPPIdentifier(const string &name, const CPPFile &file) {
_names.push_back(CPPNameComponent(name));
_native_scope = nullptr;
_loc.first_line = 0;
_loc.first_column = 0;
_loc.last_line = 0;
_loc.last_column = 0;
_loc.file = file;
}
/**
*
*/
CPPIdentifier::
CPPIdentifier(const CPPNameComponent &name, const CPPFile &file) {
_names.push_back(name);
_native_scope = nullptr;
_loc.first_line = 0;
_loc.first_column = 0;
_loc.last_line = 0;
_loc.last_column = 0;
_loc.file = file;
}
/**
*
*/
CPPIdentifier::
CPPIdentifier(const string &name, const cppyyltype &loc) : _loc(loc) {
_names.push_back(CPPNameComponent(name));
_native_scope = nullptr;
}
/**
*
*/
CPPIdentifier::
CPPIdentifier(const CPPNameComponent &name, const cppyyltype &loc) : _loc(loc) {
_names.push_back(name);
_native_scope = nullptr;
}
/**
*
*/
void CPPIdentifier::
add_name(const string &name) {
_names.push_back(CPPNameComponent(name));
}
/**
*
*/
void CPPIdentifier::
add_name(const CPPNameComponent &name) {
_names.push_back(name);
}
/**
*
*/
void CPPIdentifier::
prepend(CPPIdentifier *ident) {
_names.insert(_names.begin(), ident->_names.begin(), ident->_names.end());
}
/**
*
*/
bool CPPIdentifier::
operator == (const CPPIdentifier &other) const {
if (_names.size() != other._names.size()) {
return false;
}
for (int i = 0; i < (int)_names.size(); ++i) {
if (_names[i] != other._names[i]) {
return false;
}
}
return true;
}
/**
*
*/
bool CPPIdentifier::
operator != (const CPPIdentifier &other) const {
return !(*this == other);
}
/**
*
*/
bool CPPIdentifier::
operator < (const CPPIdentifier &other) const {
if (_names.size() != other._names.size()) {
return _names.size() < other._names.size();
}
for (int i = 0; i < (int)_names.size(); ++i) {
if (_names[i] != other._names[i]) {
return _names[i] < other._names[i];
}
}
return false;
}
/**
*
*/
bool CPPIdentifier::
is_scoped() const {
return _names.size() > 1;
}
/**
*
*/
string CPPIdentifier::
get_simple_name() const {
return _names.back().get_name();
}
/**
*
*/
string CPPIdentifier::
get_local_name(CPPScope *scope) const {
assert(!_names.empty());
string result;
if (scope == nullptr || (_native_scope == nullptr && _names.size() == 1)) {
result = _names.back().get_name_with_templ(scope);
} else if (_names.front().empty()) {
result = get_fully_scoped_name();
} else {
// Determine the scope of everything up until but not including the last
// name.
CPPScope *my_scope = get_scope(scope, nullptr);
// Strip off template scopes, since they don't add anything particularly
// meaningful to the local name.
while (my_scope != nullptr && my_scope->as_template_scope() != nullptr) {
my_scope = my_scope->get_parent_scope();
}
if (my_scope == nullptr) {
result = get_fully_scoped_name();
} else if (my_scope == scope) {
return _names.back().get_name_with_templ(scope);
} else {
result = my_scope->get_local_name(scope);
if (!result.empty()) {
result += "::";
}
result += _names.back().get_name_with_templ(scope);
}
}
return result;
}
/**
*
*/
string CPPIdentifier::
get_fully_scoped_name() const {
assert(!_names.empty());
Names::const_iterator ni = _names.begin();
string name = (*ni).get_name_with_templ();
++ni;
while (ni != _names.end()) {
name += "::" + (*ni).get_name_with_templ();
++ni;
}
return name;
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which
* has not yet been instantiated.
*/
bool CPPIdentifier::
is_fully_specified() const {
Names::const_iterator ni;
for (ni = _names.begin(); ni != _names.end(); ++ni) {
if ((*ni).has_templ() && !(*ni).get_templ()->is_fully_specified()) {
return false;
}
}
return true;
}
/**
* Returns true if the identifier includes a template parameter list that
* includes some not-yet-defined type.
*/
bool CPPIdentifier::
is_tbd() const {
Names::const_iterator ni;
for (ni = _names.begin(); ni != _names.end(); ++ni) {
if ((*ni).is_tbd()) {
return true;
}
}
return false;
}
/**
*
*/
CPPScope *CPPIdentifier::
get_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink) const {
assert(!_names.empty());
CPPScope *scope = _native_scope;
if (scope == nullptr) {
scope = current_scope;
}
int i = 0;
if (_names[i].empty()) {
// This identifier starts with a ::, thus it begins at the global scope.
scope = global_scope;
i++;
}
while (i + 1 < (int)_names.size() && scope != nullptr) {
// Check for an explicitly specialized scope first.
CPPScope *next_scope = scope->find_scope(_names[i].get_name_with_templ(), global_scope);
if (next_scope == nullptr) {
next_scope = scope->find_scope(_names[i].get_name(), global_scope);
if (next_scope == nullptr) {
if (error_sink != nullptr) {
error_sink->error("Symbol " + _names[i].get_name() +
" is not a known scope in " +
scope->get_fully_scoped_name(),
_loc);
}
return nullptr;
}
if (_names[i].has_templ()) {
next_scope = next_scope->instantiate(_names[i].get_templ(),
current_scope, global_scope);
}
}
scope = next_scope;
i++;
}
return scope;
}
/**
*
*/
CPPScope *CPPIdentifier::
get_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPDeclaration::SubstDecl &subst,
CPPPreprocessor *error_sink) const {
assert(!_names.empty());
CPPScope *scope = _native_scope;
if (scope == nullptr) {
scope = current_scope;
}
int i = 0;
if (_names[i].empty()) {
// This identifier starts with a ::, thus it begins at the global scope.
scope = global_scope;
i++;
}
while (i + 1 < (int)_names.size() && scope != nullptr) {
CPPScope *next_scope = scope->find_scope(_names[i].get_name(), subst,
global_scope);
if (next_scope == nullptr) {
if (error_sink != nullptr) {
error_sink->error("Symbol " + _names[i].get_name() +
" is not a known scope in " +
scope->get_fully_scoped_name(),
_loc);
}
return nullptr;
}
if (_names[i].has_templ()) {
next_scope = next_scope->instantiate(_names[i].get_templ(),
current_scope, global_scope);
}
scope = next_scope;
i++;
}
return scope;
}
/**
* Looks up the identifier in the current and/or global scopes, and returns a
* CPPType pointer if it seems to refer to a type, or NULL if it does not. If
* force_instantiate is true, the type will be instantiated as fully as
* possible right now, even if it means instantiating it into an identical
* template type. Otherwise, the instantiation may be delayed for
* optimization reasons, and a CPPTBDType placeholder may be returned instead.
*/
CPPType *CPPIdentifier::
find_type(CPPScope *current_scope, CPPScope *global_scope,
bool force_instantiate,
CPPPreprocessor *error_sink) const {
CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
if (scope == nullptr) {
return nullptr;
}
CPPType *type = nullptr;
if (!_names.back().has_templ()) {
type = scope->find_type(get_simple_name());
} else {
CPPDeclaration *decl = find_symbol(current_scope, global_scope, error_sink);
type = decl->as_type();
/*
if (type != NULL) {
if (!type->is_incomplete() || force_instantiate) {
type = type->instantiate(_names.back().get_templ(),
current_scope, global_scope,
error_sink)->as_type();
// If we ended up with another template, instantiate later.
if (type->is_template() && !force_instantiate) {
type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
}
} else {
// Otherwise, we'll have to instantiate the type later.
type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
}
// type->_file.replace_nearer(_file);
}
*/
}
return type;
}
/**
* This flavor of find_type() will instantiate any scope names in the
* identifier. It's useful for fully defining a type while instantiating a
* class.
*/
CPPType *CPPIdentifier::
find_type(CPPScope *current_scope, CPPScope *global_scope,
CPPDeclaration::SubstDecl &subst,
CPPPreprocessor *error_sink) const {
CPPScope *scope = get_scope(current_scope, global_scope, subst, error_sink);
if (scope == nullptr) {
return nullptr;
}
CPPType *type = scope->find_type(get_simple_name(), subst, global_scope);
if (type != nullptr && _names.back().has_templ()) {
// This is a template type.
if (is_fully_specified()) {
// If our identifier fully specifies the instantiation, then apply it.
CPPDeclaration *decl =
type->instantiate(_names.back().get_templ(),
current_scope, global_scope,
error_sink);
assert(decl != nullptr);
CPPType *new_type = decl->as_type();
assert(new_type != nullptr);
if (new_type == type) {
type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
} else {
type = new_type;
}
} else {
// Otherwise, we'll have to instantiate the type later.
type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
}
// type->_file.replace_nearer(_file);
}
return type;
}
/**
*
*/
CPPDeclaration *CPPIdentifier::
find_symbol(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink) const {
CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
if (scope == nullptr) {
return nullptr;
}
CPPDeclaration *sym;
if (!_names.back().has_templ()) {
if (_names.size() > 1 && scope->get_simple_name() == get_simple_name()) {
/**
*/
sym = scope->get_struct_type()->get_constructor();
} else {
sym = scope->find_symbol(get_simple_name());
}
} else {
sym = scope->find_template(get_simple_name());
if (sym != nullptr) {
CPPType *type = sym->as_type();
if (type != nullptr && type->is_incomplete()) {
// We can't instantiate an incomplete type.
sym = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
} else {
// Instantiate the symbol.
sym = sym->instantiate(_names.back().get_templ(), current_scope,
global_scope, error_sink);
}
}
}
return sym;
}
/**
*
*/
CPPDeclaration *CPPIdentifier::
find_symbol(CPPScope *current_scope, CPPScope *global_scope,
CPPDeclaration::SubstDecl &subst,
CPPPreprocessor *error_sink) const {
CPPScope *scope = get_scope(current_scope, global_scope, subst, error_sink);
if (scope == nullptr) {
return nullptr;
}
CPPDeclaration *sym;
if (!_names.back().has_templ()) {
if (_names.size() > 1 && scope->get_simple_name() == get_simple_name()) {
/**
*/
sym = scope->get_struct_type()->get_constructor();
} else {
sym = scope->find_symbol(get_simple_name());
}
} else {
sym = scope->find_template(get_simple_name());
if (sym != nullptr) {
CPPType *type = sym->as_type();
if (type != nullptr && type->is_incomplete()) {
// We can't instantiate an incomplete type.
sym = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
} else {
// Instantiate the symbol.
sym = sym->instantiate(_names.back().get_templ(), current_scope,
global_scope, error_sink);
}
}
}
return sym;
}
/**
*
*/
CPPDeclaration *CPPIdentifier::
find_template(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink) const {
CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
if (scope == nullptr) {
return nullptr;
}
return scope->find_template(get_simple_name());
}
/**
*
*/
CPPScope *CPPIdentifier::
find_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink) const {
CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
if (scope == nullptr) {
return nullptr;
}
return scope->find_scope(get_simple_name(), global_scope);
}
/**
*
*/
CPPIdentifier *CPPIdentifier::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
CPPIdentifier *rep = new CPPIdentifier(*this);
bool anything_changed = false;
for (int i = 0; i < (int)rep->_names.size(); ++i) {
if (_names[i].has_templ()) {
rep->_names[i].set_templ
(_names[i].get_templ()->substitute_decl(subst, current_scope, global_scope));
if (rep->_names[i].get_templ() != _names[i].get_templ()) {
anything_changed = true;
}
}
}
if (!anything_changed) {
delete rep;
rep = this;
}
return rep;
}
/**
*
*/
void CPPIdentifier::
output(std::ostream &out, CPPScope *scope) const {
if (scope == nullptr) {
output_fully_scoped_name(out);
} else {
output_local_name(out, scope);
}
}
/**
*
*/
void CPPIdentifier::
output_local_name(std::ostream &out, CPPScope *scope) const {
assert(!_names.empty());
if (scope == nullptr || (_native_scope == nullptr && _names.size() == 1)) {
out << _names.back();
} else if (_names.front().empty()) {
output_fully_scoped_name(out);
} else {
// Determine the scope of everything up until but not including the last
// name.
CPPScope *my_scope = get_scope(scope, nullptr);
if (my_scope == nullptr) {
output_fully_scoped_name(out);
} else {
out << my_scope->get_local_name(scope) << "::" << _names.back();
}
}
}
/**
*
*/
void CPPIdentifier::
output_fully_scoped_name(std::ostream &out) const {
if (_native_scope != nullptr) {
_native_scope->output(out, nullptr);
out << "::";
}
Names::const_iterator ni = _names.begin();
out << (*ni);
++ni;
while (ni != _names.end()) {
out << "::" << (*ni);
++ni;
}
}

View File

@ -1,106 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppIdentifier.h
* @author drose
* @date 1999-10-26
*/
#ifndef CPPIDENTIFIER_H
#define CPPIDENTIFIER_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
#include "cppNameComponent.h"
#include "cppFile.h"
#include "cppBisonDefs.h"
#include <string>
#include <vector>
class CPPScope;
class CPPType;
class CPPPreprocessor;
class CPPTemplateParameterList;
/**
*
*/
class CPPIdentifier {
public:
CPPIdentifier(const std::string &name, const CPPFile &file = CPPFile());
CPPIdentifier(const CPPNameComponent &name, const CPPFile &file = CPPFile());
CPPIdentifier(const std::string &name, const cppyyltype &loc);
CPPIdentifier(const CPPNameComponent &name, const cppyyltype &loc);
void add_name(const std::string &name);
void add_name(const CPPNameComponent &name);
void prepend(CPPIdentifier *ident);
bool operator == (const CPPIdentifier &other) const;
bool operator != (const CPPIdentifier &other) const;
bool operator < (const CPPIdentifier &other) const;
bool is_scoped() const;
std::string get_simple_name() const;
std::string get_local_name(CPPScope *scope = nullptr) const;
std::string get_fully_scoped_name() const;
bool is_fully_specified() const;
bool is_tbd() const;
CPPScope *get_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
CPPScope *get_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPDeclaration::SubstDecl &subst,
CPPPreprocessor *error_sink = nullptr) const;
CPPType *find_type(CPPScope *current_scope, CPPScope *global_scope,
bool force_instantiate = false,
CPPPreprocessor *error_sink = nullptr) const;
CPPType *find_type(CPPScope *current_scope, CPPScope *global_scope,
CPPDeclaration::SubstDecl &subst,
CPPPreprocessor *error_sink = nullptr) const;
CPPDeclaration *find_symbol(CPPScope *current_scope,
CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
CPPDeclaration *find_symbol(CPPScope *current_scope,
CPPScope *global_scope,
CPPDeclaration::SubstDecl &subst,
CPPPreprocessor *error_sink = nullptr) const;
CPPDeclaration *find_template(CPPScope *current_scope,
CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
CPPScope *find_scope(CPPScope *current_scope,
CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
CPPIdentifier *substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
void output(std::ostream &out, CPPScope *scope) const;
void output_local_name(std::ostream &out, CPPScope *scope) const;
void output_fully_scoped_name(std::ostream &out) const;
typedef std::vector<CPPNameComponent> Names;
Names _names;
CPPScope *_native_scope;
cppyyltype _loc;
};
inline std::ostream &operator << (std::ostream &out, const CPPIdentifier &identifier) {
identifier.output(out, nullptr);
return out;
}
#endif

View File

@ -1,637 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppInstance.cxx
* @author drose
* @date 1999-10-19
*/
#include "cppInstance.h"
#include "cppInstanceIdentifier.h"
#include "cppIdentifier.h"
#include "cppTemplateScope.h"
#include "cppFunctionType.h"
#include "cppSimpleType.h"
#include "cppExpression.h"
#include "cppPreprocessor.h"
#include "cppParameterList.h"
#include "cppReferenceType.h"
#include "cppConstType.h"
#include "indent.h"
#include <algorithm>
using std::string;
/**
*
*/
CPPInstance::
CPPInstance(CPPType *type, const string &name, int storage_class) :
CPPDeclaration(CPPFile()),
_type(type),
_ident(new CPPIdentifier(name)),
_storage_class(storage_class),
_bit_width(-1)
{
_initializer = nullptr;
}
/**
*
*/
CPPInstance::
CPPInstance(CPPType *type, CPPIdentifier *ident, int storage_class) :
CPPDeclaration(CPPFile()),
_type(type),
_ident(ident),
_storage_class(storage_class),
_bit_width(-1)
{
_initializer = nullptr;
}
/**
* Constructs a new CPPInstance object that defines a variable of the
* indicated type according to the type and the InstanceIdentifier. The
* InstanceIdentifier pointer is deallocated.
*/
CPPInstance::
CPPInstance(CPPType *type, CPPInstanceIdentifier *ii, int storage_class,
const CPPFile &file) :
CPPDeclaration(file)
{
_type = ii->unroll_type(type);
_ident = ii->_ident;
_attributes = ii->_attributes;
ii->_ident = nullptr;
_storage_class = storage_class;
_initializer = nullptr;
if (ii->_bit_width != nullptr) {
CPPExpression::Result result = ii->_bit_width->evaluate();
if (result._type != CPPExpression::RT_error) {
_bit_width = ii->_bit_width->evaluate().as_integer();
} else {
_bit_width = -1;
}
} else {
_bit_width = -1;
}
CPPParameterList *params = ii->get_initializer();
if (params != nullptr) {
// In this case, the instance has a parameter-list initializer, e.g.: int
// foo(0); We really should save this initializer in the instance object.
// But we don't for now, since no one really cares about initializers
// anyway.
}
if (ii->_packed) {
_storage_class |= SC_parameter_pack;
}
delete ii;
}
/**
*
*/
CPPInstance::
CPPInstance(const CPPInstance &copy) :
CPPDeclaration(copy),
_type(copy._type),
_ident(copy._ident),
_initializer(copy._initializer),
_storage_class(copy._storage_class),
_bit_width(copy._bit_width)
{
assert(_type != nullptr);
}
/**
*
*/
CPPInstance::
~CPPInstance() {
// Can't delete the identifier. Don't try.
}
/**
* Constructs and returns a new CPPInstance object that corresponds to a
* function prototype declaration for a typecast method, whose return type is
* implicit in the identifier type.
*/
CPPInstance *CPPInstance::
make_typecast_function(CPPInstance *inst, CPPIdentifier *ident,
CPPParameterList *parameters, int function_flags) {
CPPType *type = CPPType::new_type(inst->_type);
delete inst;
function_flags |= (int)CPPFunctionType::F_operator_typecast;
CPPType *ft =
CPPType::new_type(new CPPFunctionType(type, parameters, function_flags));
return new CPPInstance(ft, ident);
}
/**
*
*/
bool CPPInstance::
operator == (const CPPInstance &other) const {
if (_type != other._type) {
return false;
}
if (_storage_class != other._storage_class) {
return false;
}
if (_attributes != other._attributes) {
return false;
}
// We *do* care about the identifier. We need to differentiate types of
// function variables, among possibly other things, based on the identifier.
if ((_ident == nullptr && other._ident != nullptr) ||
(_ident != nullptr && other._ident == nullptr) ||
(_ident != nullptr && other._ident != nullptr && *_ident != *other._ident))
{
return false;
}
// We similarly care about the initializer.
if ((_initializer == nullptr && other._initializer != nullptr) ||
(_initializer != nullptr && other._initializer == nullptr) ||
(_initializer != nullptr && other._initializer != nullptr &&
*_initializer != *other._initializer))
{
return false;
}
return true;
}
/**
*
*/
bool CPPInstance::
operator != (const CPPInstance &other) const {
return !operator == (other);
}
/**
*
*/
bool CPPInstance::
operator < (const CPPInstance &other) const {
if (_type != other._type) {
return _type < other._type;
}
if (_storage_class != other._storage_class) {
return _storage_class < other._storage_class;
}
if (_attributes != other._attributes) {
return _attributes < other._attributes;
}
// We *do* care about the identifier. We need to differentiate types of
// function variables, among possibly other things, based on the identifier.
if ((_ident == nullptr && other._ident != nullptr) ||
(_ident != nullptr && other._ident == nullptr) ||
(_ident != nullptr && other._ident != nullptr && *_ident != *other._ident))
{
if (_ident == nullptr || other._ident == nullptr) {
return _ident < other._ident;
}
return *_ident < *other._ident;
}
// We similarly care about the initializer.
if ((_initializer == nullptr && other._initializer != nullptr) ||
(_initializer != nullptr && other._initializer == nullptr) ||
(_initializer != nullptr && other._initializer != nullptr &&
*_initializer != *other._initializer))
{
if (_initializer == nullptr || other._initializer == nullptr) {
return _initializer < other._initializer;
}
return *_initializer < *other._initializer;
}
return false;
}
/**
* Sets the value of the expression that is used to initialize the variable,
* or the default value for a parameter. If a non-null expression is set on a
* function declaration, it implies that the function is pure virtual.
*/
void CPPInstance::
set_initializer(CPPExpression *initializer) {
if (_type->as_function_type() != nullptr) {
// This is a function declaration.
_storage_class &= ~(SC_pure_virtual | SC_defaulted | SC_deleted);
_initializer = nullptr;
if (initializer != nullptr) {
if (initializer->_type == CPPExpression::T_integer) { // = 0
_storage_class |= SC_pure_virtual;
} else if (initializer->_type == CPPExpression::T_default) {
_storage_class |= SC_defaulted;
} else if (initializer->_type == CPPExpression::T_delete) {
_storage_class |= SC_deleted;
}
}
} else {
_initializer = initializer;
}
}
/**
* Sets the number of bytes to align this instance to.
*/
void CPPInstance::
set_alignment(int align) {
_attributes.add_alignas(align);
}
/**
* Sets the expression that is used to determine the required alignment for
* the variable. This should be a constant expression, but we don't presently
* verify that it is.
*/
void CPPInstance::
set_alignment(CPPExpression *const_expr) {
_attributes.add_alignas(const_expr);
}
/**
*
*/
bool CPPInstance::
is_scoped() const {
if (_ident == nullptr) {
return false;
} else {
return _ident->is_scoped();
}
}
/**
*
*/
CPPScope *CPPInstance::
get_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink) const {
if (_ident == nullptr) {
return current_scope;
} else {
return _ident->get_scope(current_scope, global_scope, error_sink);
}
}
/**
*
*/
string CPPInstance::
get_simple_name() const {
if (_ident == nullptr) {
return "";
} else {
return _ident->get_simple_name();
}
}
/**
*
*/
string CPPInstance::
get_local_name(CPPScope *scope) const {
if (_ident == nullptr) {
return "";
} else {
return _ident->get_local_name(scope);
}
}
/**
*
*/
string CPPInstance::
get_fully_scoped_name() const {
if (_ident == nullptr) {
return "";
} else {
return _ident->get_fully_scoped_name();
}
}
/**
* If this is a function type instance, checks whether the function name
* matches the class name (or ~name), and if so, flags it as a constructor,
* destructor or assignment operator
*/
void CPPInstance::
check_for_constructor(CPPScope *current_scope, CPPScope *global_scope) {
CPPScope *scope = get_scope(current_scope, global_scope);
if (scope == nullptr) {
scope = current_scope;
}
CPPFunctionType *func = _type->as_function_type();
if (func != nullptr && scope != nullptr) {
string method_name = get_local_name(scope);
string class_name = scope->get_local_name();
if (!method_name.empty() && !class_name.empty()) {
// Check either a constructor or assignment operator.
if (method_name == class_name || method_name == "operator =") {
CPPType *void_type = CPPType::new_type
(new CPPSimpleType(CPPSimpleType::T_void));
int flags = func->_flags;
if (method_name == class_name) {
flags |= CPPFunctionType::F_constructor;
}
CPPParameterList *params = func->_parameters;
if (params->_parameters.size() == 1 && !params->_includes_ellipsis) {
CPPType *param_type = params->_parameters[0]->_type;
CPPReferenceType *ref_type = param_type->as_reference_type();
if (ref_type != nullptr) {
param_type = ref_type->_pointing_at->remove_cv();
if (class_name == param_type->get_simple_name()) {
if (flags & CPPFunctionType::F_constructor) {
if (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
flags |= CPPFunctionType::F_move_constructor;
} else {
flags |= CPPFunctionType::F_copy_constructor;
}
} else {
if (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
flags |= CPPFunctionType::F_move_assignment_operator;
} else {
flags |= CPPFunctionType::F_copy_assignment_operator;
}
}
}
}
}
_type = CPPType::new_type
(new CPPFunctionType(void_type, func->_parameters, flags));
} else if (method_name == "~" + class_name) {
CPPType *void_type = CPPType::new_type
(new CPPSimpleType(CPPSimpleType::T_void));
_type = CPPType::new_type
(new CPPFunctionType(void_type, func->_parameters,
func->_flags | CPPFunctionType::F_destructor));
}
}
}
}
/**
*
*/
CPPDeclaration *CPPInstance::
instantiate(const CPPTemplateParameterList *actual_params,
CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink) const {
if (!is_template()) {
if (error_sink != nullptr) {
error_sink->warning("Ignoring template parameters for instance " +
_ident->get_local_name());
}
return (CPPInstance *)this;
}
Instantiations::const_iterator ii;
ii = _instantiations.find(actual_params);
if (ii != _instantiations.end()) {
// We've already instantiated this instance with these parameters. Return
// that.
return (*ii).second;
}
CPPTemplateScope *tscope = get_template_scope();
CPPDeclaration::SubstDecl subst;
actual_params->build_subst_decl(tscope->_parameters, subst,
current_scope, global_scope);
CPPInstance *inst =
((CPPInstance *)this)->substitute_decl(subst, current_scope, global_scope)
->as_instance();
if (inst == this) {
// Hmm, nothing to substitute. Make a new instance anyway, so we can
// change the name.
inst = new CPPInstance(*this);
}
assert(inst != nullptr);
inst->_ident = inst->_ident->substitute_decl(subst, current_scope, global_scope);
if (inst->_ident == _ident) {
inst->_ident = new CPPIdentifier(*inst->_ident);
}
inst->_ident->_names.back().set_templ
(new CPPTemplateParameterList(*actual_params));
inst->_template_scope = nullptr;
((CPPInstance *)this)->_instantiations.insert(Instantiations::value_type(actual_params, inst));
return inst;
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which
* has not yet been instantiated.
*/
bool CPPInstance::
is_fully_specified() const {
if (_ident != nullptr && !_ident->is_fully_specified()) {
return false;
}
if (_initializer != nullptr && !_initializer->is_fully_specified()) {
return false;
}
return CPPDeclaration::is_fully_specified() &&
_type->is_fully_specified();
}
/**
*
*/
CPPDeclaration *CPPInstance::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
CPPDeclaration *top =
CPPDeclaration::substitute_decl(subst, current_scope, global_scope);
if (top != this) {
return top;
}
CPPInstance *rep = new CPPInstance(*this);
CPPDeclaration *new_type =
_type->substitute_decl(subst, current_scope, global_scope);
rep->_type = new_type->as_type();
if (rep->_type == nullptr) {
rep->_type = _type;
}
if (_initializer != nullptr) {
rep->_initializer =
_initializer->substitute_decl(subst, current_scope, global_scope)
->as_expression();
}
if (rep->_type == _type &&
rep->_initializer == _initializer) {
delete rep;
rep = this;
}
subst.insert(SubstDecl::value_type(this, rep));
return rep;
}
/**
*
*/
void CPPInstance::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
output(out, indent_level, scope, complete, -1);
}
/**
* The extra parameter comes into play only when we happen to be outputting a
* function prototype. See CPPFunctionType::output().
*/
void CPPInstance::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete,
int num_default_parameters) const {
assert(_type != nullptr);
if (_type->is_parameter_expr()) {
// In this case, the whole thing is really an expression, and not an
// instance at all. This can only happen if we parsed an instance
// declaration while we thought we were parsing a function prototype.
out << *_initializer;
return;
}
if (is_template()) {
get_template_scope()->_parameters.write_formal(out, scope);
indent(out, indent_level);
}
if (!_attributes.is_empty()) {
out << _attributes << " ";
}
if (_storage_class & SC_static) {
out << "static ";
}
if (_storage_class & SC_extern) {
out << "extern ";
}
if (_storage_class & SC_c_binding) {
out << "\"C\" ";
}
if (_storage_class & SC_virtual) {
out << "virtual ";
}
if (_storage_class & SC_inline) {
out << "inline ";
}
if (_storage_class & SC_explicit) {
out << "explicit ";
}
if (_storage_class & SC_register) {
out << "register ";
}
if (_storage_class & SC_volatile) {
out << "volatile ";
}
if (_storage_class & SC_mutable) {
out << "mutable ";
}
if (_storage_class & SC_consteval) {
out << "consteval ";
}
if (_storage_class & SC_constexpr) {
out << "constexpr ";
}
if (_storage_class & SC_constinit) {
out << "constinit ";
}
if (_storage_class & SC_thread_local) {
out << "thread_local ";
}
string name;
if (_ident != nullptr) {
name = _ident->get_local_name(scope);
}
if (_storage_class & SC_parameter_pack) {
name = "..." + name;
}
if (_type->as_function_type()) {
_type->as_function_type()->
output_instance(out, indent_level, scope, complete, "", name,
num_default_parameters);
}
else {
_type->output_instance(out, indent_level, scope, complete, "", name);
}
if (_bit_width != -1) {
out << " : " << _bit_width;
}
if (_storage_class & SC_pure_virtual) {
out << " = 0";
}
if (_storage_class & SC_defaulted) {
out << " = default";
}
if (_storage_class & SC_deleted) {
out << " = delete";
}
if (_initializer != nullptr) {
out << " = " << *_initializer;
}
}
/**
*
*/
CPPDeclaration::SubType CPPInstance::
get_subtype() const {
return ST_instance;
}
/**
*
*/
CPPInstance *CPPInstance::
as_instance() {
return this;
}

View File

@ -1,138 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppInstance.h
* @author drose
* @date 1999-10-19
*/
#ifndef CPPINSTANCE_H
#define CPPINSTANCE_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
#include "cppType.h"
#include "cppTemplateParameterList.h"
#include "cppAttributeList.h"
class CPPInstanceIdentifier;
class CPPIdentifier;
class CPPParameterList;
class CPPScope;
class CPPExpression;
/**
*
*/
class CPPInstance : public CPPDeclaration {
public:
// Some of these flags clearly only make sense in certain contexts, e.g.
// for a function or method.
enum StorageClass {
SC_static = 0x0001,
SC_extern = 0x0002,
SC_c_binding = 0x0004,
SC_virtual = 0x0008,
SC_inline = 0x0010,
SC_explicit = 0x0020,
SC_register = 0x0040,
SC_pure_virtual = 0x0080,
SC_volatile = 0x0100,
SC_mutable = 0x0200,
SC_consteval = 0x080000,
SC_constexpr = 0x000400,
SC_constinit = 0x100000,
// This bit is only set by CPPStructType::check_virtual().
SC_inherited_virtual = 0x0800,
// This is a special "storage class" for methods tagged with the BLOCKING
// macro (i.e. the special __blocking keyword). These are methods that
// might block and therefore need to release Python threads for their
// duration.
SC_blocking = 0x1000,
// And this is for methods tagged with __extension, which declares
// extension methods defined separately from the source code.
SC_extension = 0x2000,
// These are for =default and =delete functions.
SC_defaulted = 0x4000,
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 std::string &name, int storage_class = 0);
CPPInstance(CPPType *type, CPPIdentifier *ident, int storage_class = 0);
CPPInstance(CPPType *type, CPPInstanceIdentifier *ii,
int storage_class, const CPPFile &file);
CPPInstance(const CPPInstance &copy);
~CPPInstance();
static CPPInstance *
make_typecast_function(CPPInstance *inst, CPPIdentifier *ident,
CPPParameterList *parameters, int function_flags);
bool operator == (const CPPInstance &other) const;
bool operator != (const CPPInstance &other) const;
bool operator < (const CPPInstance &other) const;
void set_initializer(CPPExpression *initializer);
void set_alignment(int align);
void set_alignment(CPPExpression *const_expr);
bool is_scoped() const;
CPPScope *get_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
std::string get_simple_name() const;
std::string get_local_name(CPPScope *scope = nullptr) const;
std::string get_fully_scoped_name() const;
void check_for_constructor(CPPScope *current_scope, CPPScope *global_scope);
virtual CPPDeclaration *
instantiate(const CPPTemplateParameterList *actual_params,
CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
virtual bool is_fully_specified() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete, int num_default_parameters) const;
virtual SubType get_subtype() const;
virtual CPPInstance *as_instance();
CPPType *_type;
CPPIdentifier *_ident;
CPPExpression *_initializer;
int _storage_class;
int _bit_width;
private:
typedef std::map<const CPPTemplateParameterList *, CPPInstance *, CPPTPLCompare> Instantiations;
Instantiations _instantiations;
};
#endif

View File

@ -1,345 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppInstanceIdentifier.cxx
* @author drose
* @date 1999-10-21
*/
#include "cppInstanceIdentifier.h"
#include "cppPointerType.h"
#include "cppReferenceType.h"
#include "cppArrayType.h"
#include "cppConstType.h"
#include "cppFunctionType.h"
#include "cppSimpleType.h"
#include "cppParameterList.h"
#include "cppIdentifier.h"
/**
*
*/
CPPInstanceIdentifier::Modifier::
Modifier(CPPInstanceIdentifierType type, CPPAttributeList attr) :
_type(type),
_func_params(nullptr),
_func_flags(0),
_scoping(nullptr),
_expr(nullptr),
_attributes(std::move(attr)) {
}
/**
*
*/
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
func_type(CPPParameterList *params, int flags, CPPType *trailing_return_type,
CPPAttributeList attr) {
Modifier mod(IIT_func, std::move(attr));
mod._func_params = params;
mod._func_flags = flags;
mod._trailing_return_type = trailing_return_type;
return mod;
}
/**
*
*/
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
array_type(CPPExpression *expr, CPPAttributeList attr) {
Modifier mod(IIT_array, std::move(attr));
mod._expr = expr;
return mod;
}
/**
*
*/
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
scoped_pointer_type(CPPIdentifier *scoping, CPPAttributeList attr) {
Modifier mod(IIT_scoped_pointer, std::move(attr));
mod._scoping = scoping;
return mod;
}
/**
* This is used only for instance declarations that turn out to be have a
* parameter list for an initializer.
*/
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
initializer_type(CPPParameterList *params) {
Modifier mod(IIT_initializer);
mod._func_params = params;
return mod;
}
/**
*
*/
CPPInstanceIdentifier::
CPPInstanceIdentifier(CPPIdentifier *ident) :
_ident(ident),
_bit_width(nullptr),
_packed(false) {
}
/**
*
*/
CPPInstanceIdentifier::
CPPInstanceIdentifier(CPPIdentifier *ident, CPPAttributeList attributes) :
_ident(ident),
_attributes(std::move(attributes)),
_bit_width(nullptr),
_packed(false) {
}
/**
* Unrolls the list of type punctuation on either side of the identifier to
* determine the actual type represented by the identifier, given the
* indicated starting type (that is, the type name written to the left of the
* identifier).
*/
CPPType *CPPInstanceIdentifier::
unroll_type(CPPType *start_type) {
CPPType *result = r_unroll_type(start_type, _modifiers.begin());
return result;
}
/**
*
*/
void CPPInstanceIdentifier::
add_modifier(CPPInstanceIdentifierType type, CPPAttributeList attr) {
_modifiers.push_back(Modifier(type, std::move(attr)));
}
/**
*
*/
void CPPInstanceIdentifier::
add_func_modifier(CPPParameterList *params, int flags,
CPPType *trailing_return_type, CPPAttributeList attr) {
// As a special hack, if we added a parameter list to an operator function,
// check if the parameter list is empty. If it is, this is really a unary
// operator, so set the unary_op flag. Operators () and [] are never
// considered unary operators.
if (_ident != nullptr &&
_ident->get_simple_name().substr(0, 9) == "operator ") {
if (_ident->get_simple_name() != std::string("operator ()") &&
_ident->get_simple_name() != std::string("operator []")) {
if (params->_parameters.empty()) {
flags |= CPPFunctionType::F_unary_op;
}
}
flags |= CPPFunctionType::F_operator;
}
if (trailing_return_type != nullptr) {
// Remember whether trailing return type notation was used.
flags |= CPPFunctionType::F_trailing_return_type;
}
_modifiers.push_back(Modifier::func_type(params, flags, trailing_return_type, std::move(attr)));
}
/**
*
*/
void CPPInstanceIdentifier::
add_scoped_pointer_modifier(CPPIdentifier *scoping, CPPAttributeList attr) {
_modifiers.push_back(Modifier::scoped_pointer_type(scoping, std::move(attr)));
}
/**
*
*/
void CPPInstanceIdentifier::
add_array_modifier(CPPExpression *expr, CPPAttributeList attr) {
// Special case for operator new[] and delete[]. We're not really adding an
// array modifier to them, but appending [] to the identifier. This is to
// work around a parser ambiguity.
if (_ident != nullptr && (_ident->get_simple_name() == "operator delete" ||
_ident->get_simple_name() == "operator new")) {
_ident->_names.back().append_name("[]");
} else {
_modifiers.push_back(Modifier::array_type(expr, std::move(attr)));
}
}
/**
*
*/
void CPPInstanceIdentifier::
add_initializer_modifier(CPPParameterList *params) {
_modifiers.push_back(Modifier::initializer_type(params));
}
/**
*
*/
void CPPInstanceIdentifier::
add_trailing_return_type(CPPType *type) {
// This is an awkward hack. Improve in the future.
if (!_modifiers.empty()) {
Modifier &mod = _modifiers.back();
if (mod._type == IIT_func) {
mod._trailing_return_type = type;
mod._func_flags |= CPPFunctionType::F_trailing_return_type;
return;
}
}
std::cerr << "trailing return type can only be added to a function\n";
}
/**
* Add attributes to the instance (not the type).
*/
void CPPInstanceIdentifier::
add_attributes(const CPPAttributeList &attributes) {
_attributes.add_attributes_from(attributes);
}
/**
* Returns the initializer parameter list that was set for this particular
* instance, e.g. if the instance were:
*
* int foo(0);
*
* this would return the parameter list (0). Returns NULL if the instance did
* not use a parameter list initializer.
*/
CPPParameterList *CPPInstanceIdentifier::
get_initializer() const {
Modifiers::const_iterator mi;
for (mi = _modifiers.begin(); mi != _modifiers.end(); ++mi) {
const Modifier &mod = (*mi);
if (mod._type == IIT_initializer) {
return mod._func_params;
}
}
return nullptr;
}
/**
*
*/
CPPScope *CPPInstanceIdentifier::
get_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink) const {
if (_ident == nullptr) {
return current_scope;
} else {
return _ident->get_scope(current_scope, global_scope, error_sink);
}
}
/**
* The recursive implementation of unroll_type().
*/
CPPType *CPPInstanceIdentifier::
r_unroll_type(CPPType *start_type,
CPPInstanceIdentifier::Modifiers::const_iterator mi) {
assert(start_type != nullptr);
start_type = CPPType::new_type(start_type);
if (mi == _modifiers.end()) {
return start_type;
}
const Modifier &mod = (*mi);
++mi;
CPPType *result = nullptr;
switch (mod._type) {
case IIT_pointer:
result = new CPPPointerType(r_unroll_type(start_type, mi));
break;
case IIT_reference:
result = new CPPReferenceType(r_unroll_type(start_type, mi),
CPPReferenceType::VC_lvalue);
break;
case IIT_rvalue_reference:
result = new CPPReferenceType(r_unroll_type(start_type, mi),
CPPReferenceType::VC_rvalue);
break;
case IIT_scoped_pointer:
{
CPPType *type = r_unroll_type(start_type, mi);
CPPFunctionType *ftype = type->as_function_type();
if (ftype != nullptr) {
ftype = new CPPFunctionType(*ftype);
ftype->_class_owner = mod._scoping;
ftype->_flags |= CPPFunctionType::F_method_pointer;
type = ftype;
}
result = new CPPPointerType(type);
}
break;
case IIT_array:
result = new CPPArrayType(r_unroll_type(start_type, mi),
mod._expr);
break;
case IIT_const:
result = new CPPConstType(r_unroll_type(start_type, mi));
break;
case IIT_volatile:
case IIT_restrict:
// Just pass it through for now.
result = r_unroll_type(start_type, mi);
break;
case IIT_paren:
result = r_unroll_type(start_type, mi);
break;
case IIT_func:
{
CPPType *return_type = r_unroll_type(start_type, mi);
if (mod._trailing_return_type != nullptr) {
CPPSimpleType *simple_type = return_type->as_simple_type();
if (simple_type != nullptr && simple_type->_type == CPPSimpleType::T_auto) {
return_type = mod._trailing_return_type;
} else {
std::cerr << "function with trailing return type needs auto\n";
}
}
result = new CPPFunctionType(return_type, mod._func_params,
mod._func_flags);
}
break;
case IIT_initializer:
// In this case, we have parsed an instance declaration with a set of
// initializers as a parameter list. We lose the initializers at this
// point, but the instance will put it back again.
result = start_type;
break;
default:
std::cerr << "Internal error--invalid CPPInstanceIdentifier\n";
abort();
}
result->_attributes = mod._attributes;
return CPPType::new_type(result);
}

View File

@ -1,115 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppInstanceIdentifier.h
* @author drose
* @date 1999-10-21
*/
#ifndef CPPINSTANCEIDENTIFIER_H
#define CPPINSTANCEIDENTIFIER_H
#include "dtoolbase.h"
#include "cppAttributeList.h"
#include <vector>
#include <string>
class CPPIdentifier;
class CPPParameterList;
class CPPType;
class CPPExpression;
class CPPScope;
class CPPPreprocessor;
enum CPPInstanceIdentifierType {
IIT_pointer,
IIT_reference,
IIT_rvalue_reference,
IIT_scoped_pointer,
IIT_array,
IIT_const,
IIT_volatile,
IIT_restrict,
IIT_paren,
IIT_func,
IIT_initializer,
};
/**
* This class is used in parser.y to build up a variable instance definition.
* An instance is something like 'int *&a'; the InstanceIdentifier stores
* everything to the right of the typename. Later this can be passed to
* make_instance() to construct a CPPInstance.
*/
class CPPInstanceIdentifier {
public:
CPPInstanceIdentifier(CPPIdentifier *ident);
CPPInstanceIdentifier(CPPIdentifier *ident, CPPAttributeList attributes);
CPPType *unroll_type(CPPType *start_type);
void add_modifier(CPPInstanceIdentifierType type,
CPPAttributeList attr = CPPAttributeList());
void add_func_modifier(CPPParameterList *params, int flags,
CPPType *trailing_return_type = nullptr,
CPPAttributeList attr = CPPAttributeList());
void add_scoped_pointer_modifier(CPPIdentifier *scoping,
CPPAttributeList attr = CPPAttributeList());
void add_array_modifier(CPPExpression *expr,
CPPAttributeList attr = CPPAttributeList());
void add_initializer_modifier(CPPParameterList *params);
void add_trailing_return_type(CPPType *type);
void add_attributes(const CPPAttributeList &attributes);
CPPParameterList *get_initializer() const;
CPPScope *get_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
CPPIdentifier *_ident;
class Modifier {
public:
Modifier(CPPInstanceIdentifierType type,
CPPAttributeList attr = CPPAttributeList());
static Modifier func_type(CPPParameterList *params, int flags,
CPPType *trailing_return_type,
CPPAttributeList attr);
static Modifier array_type(CPPExpression *expr, CPPAttributeList attr);
static Modifier scoped_pointer_type(CPPIdentifier *scoping,
CPPAttributeList attr);
static Modifier initializer_type(CPPParameterList *params);
CPPInstanceIdentifierType _type;
CPPParameterList *_func_params;
int _func_flags;
CPPIdentifier *_scoping;
CPPExpression *_expr;
CPPType *_trailing_return_type;
CPPAttributeList _attributes;
};
typedef std::vector<Modifier> Modifiers;
Modifiers _modifiers;
CPPAttributeList _attributes;
// If not null, indicates a bitfield
CPPExpression *_bit_width;
// Indicates a parameter pack
bool _packed;
private:
CPPType *
r_unroll_type(CPPType *start_type, Modifiers::const_iterator mi);
};
#endif

View File

@ -1,122 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppMakeProperty.cxx
* @author rdb
* @date 2014-09-18
*/
#include "cppMakeProperty.h"
#include "cppFunctionGroup.h"
/**
*
*/
CPPMakeProperty::
CPPMakeProperty(CPPIdentifier *ident, Type type,
CPPScope *current_scope, const CPPFile &file) :
CPPDeclaration(file),
_ident(ident),
_type(type),
_length_function(nullptr),
_has_function(nullptr),
_get_function(nullptr),
_set_function(nullptr),
_clear_function(nullptr),
_del_function(nullptr),
_insert_function(nullptr),
_get_key_function(nullptr)
{
_ident->_native_scope = current_scope;
}
/**
*
*/
std::string CPPMakeProperty::
get_simple_name() const {
return _ident->get_simple_name();
}
/**
*
*/
std::string CPPMakeProperty::
get_local_name(CPPScope *scope) const {
return _ident->get_local_name(scope);
}
/**
*
*/
std::string CPPMakeProperty::
get_fully_scoped_name() const {
return _ident->get_fully_scoped_name();
}
/**
*
*/
void CPPMakeProperty::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
if (_length_function != nullptr) {
out << "__make_seq_property";
} else {
out << "__make_property";
}
if (_has_function != nullptr) {
out.put('2');
}
out << "(" << _ident->get_local_name(scope);
if (_length_function != nullptr) {
out << ", " << _length_function->_name;
}
if (_has_function != nullptr) {
out << ", " << _has_function->_name;
}
out << ", " << _get_function->_name;
if (_set_function != nullptr) {
out << ", " << _set_function->_name;
}
if (_clear_function != nullptr) {
out << ", " << _clear_function->_name;
}
if (_del_function != nullptr) {
out << ", " << _del_function->_name;
}
if (_insert_function != nullptr) {
out << ", " << _insert_function->_name;
}
out << ");";
}
/**
*
*/
CPPDeclaration::SubType CPPMakeProperty::
get_subtype() const {
return ST_make_property;
}
/**
*
*/
CPPMakeProperty *CPPMakeProperty::
as_make_property() {
return this;
}

View File

@ -1,116 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppMakeProperty.h
* @author rdb
* @date 2014-09-18
*/
#ifndef CPPMAKEPROPERTY_H
#define CPPMAKEPROPERTY_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
#include "cppIdentifier.h"
/**
* This is a MAKE_PROPERTY() declaration appearing within a class body. It
* means to generate a property within Python, replacing (for instance)
* get_something()/set_something() with a synthetic 'something' attribute.
*
* This is an example of a simple property (MAKE_PROPERTY is defined as
* the built-in __make_property):
* @@code
* Thing get_thing() const;
* void set_thing(const Thing &);
*
* MAKE_PROPERTY(thing, get_thing, set_thing);
* @@endcode
* The setter may be omitted to make the property read-only.
*
* There is also a secondary macro that allows the property to be set to a
* cleared state using separate clear functions. In the scripting language,
* this would be represented by a "null" value, or an "optional" construct in
* languages that have no notion of a null value.
*
* @@code
* bool has_thing() const;
* Thing get_thing() const;
* void set_thing(const Thing &);
* void clear_thing();
* MAKE_PROPERTY2(thing, has_thing, get_thing, set_thing, clear_thing);
* @@endcode
* As with MAKE_PROPERTY, both the setter and clearer can be omitted to create
* a read-only property.
*
* Thirdly, there is a variant called MAKE_SEQ_PROPERTY. It takes a length
* function as argument and the getter and setter take an index as first
* argument:
* @@code
* size_t get_num_things() const;
* Thing &get_thing(size_t i) const;
* void set_thing(size_t i, Thing value) const;
* void remove_thing(size_t i) const;
*
* MAKE_SEQ_PROPERTY(get_num_things, get_thing, set_thing, remove_thing);
* @@endcode
*
* Lastly, there is the possibility to have properties with key/value
* associations, often called a "map" or "dictionary" in scripting languages:
* @@code
* bool has_thing(string key) const;
* Thing &get_thing(string key) const;
* void set_thing(string key, Thing value) const;
* void clear_thing(string key) const;
*
* MAKE_MAP_PROPERTY(things, has_thing, get_thing, set_thing, clear_thing);
* @@endcode
* You may also replace the "has" function with a "find" function that returns
* an index. If the returned index is negative (or in the case of an unsigned
* integer, the maximum value), the item is assumed not to be present in the
* mapping.
*
* It is also possible to use both MAKE_SEQ_PROPERTY and MAKE_MAP_PROPERTY on
* the same property name. This implies that this property has both a
* sequence and mapping interface.
*/
class CPPMakeProperty : public CPPDeclaration {
public:
enum Type {
T_normal = 0x0,
T_sequence = 0x1,
T_mapping = 0x2,
};
CPPMakeProperty(CPPIdentifier *ident, Type type,
CPPScope *current_scope, const CPPFile &file);
virtual std::string get_simple_name() const;
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
virtual std::string get_fully_scoped_name() const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPMakeProperty *as_make_property();
CPPIdentifier *_ident;
Type _type;
CPPFunctionGroup *_length_function;
CPPFunctionGroup *_has_function;
CPPFunctionGroup *_get_function;
CPPFunctionGroup *_set_function;
CPPFunctionGroup *_clear_function;
CPPFunctionGroup *_del_function;
CPPFunctionGroup *_insert_function;
CPPFunctionGroup *_get_key_function;
};
#endif

View File

@ -1,81 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppMakeSeq.cxx
* @author drose
* @date 2008-11-06
*/
#include "cppMakeSeq.h"
/**
*
*/
CPPMakeSeq::
CPPMakeSeq(CPPIdentifier *ident,
CPPFunctionGroup *length_getter,
CPPFunctionGroup *element_getter,
CPPScope *current_scope, const CPPFile &file) :
CPPDeclaration(file),
_ident(ident),
_length_getter(length_getter),
_element_getter(element_getter)
{
_ident->_native_scope = current_scope;
}
/**
*
*/
std::string CPPMakeSeq::
get_simple_name() const {
return _ident->get_simple_name();
}
/**
*
*/
std::string CPPMakeSeq::
get_local_name(CPPScope *scope) const {
return _ident->get_local_name(scope);
}
/**
*
*/
std::string CPPMakeSeq::
get_fully_scoped_name() const {
return _ident->get_fully_scoped_name();
}
/**
*
*/
void CPPMakeSeq::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
out << "__make_seq(" << _ident->get_local_name(scope)
<< ", " << _length_getter->_name
<< ", " << _element_getter->_name
<< ");";
}
/**
*
*/
CPPDeclaration::SubType CPPMakeSeq::
get_subtype() const {
return ST_make_seq;
}
/**
*
*/
CPPMakeSeq *CPPMakeSeq::
as_make_seq() {
return this;
}

View File

@ -1,50 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppMakeSeq.h
* @author drose
* @date 2008-11-06
*/
#ifndef CPPMAKESEQ_H
#define CPPMAKESEQ_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
#include "cppIdentifier.h"
#include "cppFunctionGroup.h"
/**
* This is a MAKE_SEQ() declaration appearing within a class body. It means
* to generate a sequence method within Python, replacing (for instance)
* get_num_nodes()/get_node(n) with a synthetic get_nodes() method.
*/
class CPPMakeSeq : public CPPDeclaration {
public:
CPPMakeSeq(CPPIdentifier *ident,
CPPFunctionGroup *length_getter,
CPPFunctionGroup *element_getter,
CPPScope *current_scope, const CPPFile &file);
virtual std::string get_simple_name() const;
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
virtual std::string get_fully_scoped_name() const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPMakeSeq *as_make_seq();
CPPIdentifier *_ident;
CPPFunctionGroup *_length_getter;
CPPFunctionGroup *_element_getter;
};
#endif

View File

@ -1,672 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppManifest.cxx
* @author drose
* @date 1999-10-22
*/
#include "cppManifest.h"
#include "cppExpression.h"
#include "cppPreprocessor.h"
#include <ctype.h>
using std::string;
/**
*
*/
CPPManifest::ExpansionNode::
ExpansionNode(int parm_number, bool stringify, bool paste) :
_parm_number(parm_number),
_expand(!stringify && !paste),
_stringify(stringify),
_paste(paste),
_optional(false)
{
}
/**
*
*/
CPPManifest::ExpansionNode::
ExpansionNode(const string &str, bool paste) :
_parm_number(-1),
_expand(!paste),
_stringify(false),
_paste(paste),
_optional(false),
_str(str)
{
}
/**
*
*/
CPPManifest::ExpansionNode::
ExpansionNode(Expansion nested, bool stringify, bool paste, bool optional) :
_parm_number(-1),
_expand(!stringify && !paste),
_stringify(stringify),
_paste(paste),
_optional(optional),
_nested(std::move(nested))
{
}
/**
*
*/
bool CPPManifest::ExpansionNode::
operator ==(const ExpansionNode &other) const {
return _parm_number == other._parm_number
&& _expand == other._expand
&& _stringify == other._stringify
&& _paste == other._paste
&& _optional == other._optional
&& _str == other._str
&& _nested == other._nested;
}
/**
* Creates a manifest from a preprocessor definition.
*/
CPPManifest::
CPPManifest(const CPPPreprocessor &parser, const string &args, const cppyyltype &loc) :
_parser(parser),
_variadic_param(-1),
_loc(loc),
_expr(nullptr),
_vis(V_public)
{
assert(!args.empty());
assert(!isspace(args[0]));
// First, identify the manifest name.
size_t p = 0;
while (p < args.size() && !isspace(args[p]) && args[p] != '(') {
p++;
}
_name = args.substr(0, p);
vector_string parameter_names;
if (args[p] == '(') {
// Hmm, parameters.
_has_parameters = true;
parse_parameters(args, p, parameter_names);
_num_parameters = parameter_names.size();
p++;
} else {
_has_parameters = false;
_num_parameters = 0;
}
// Now identify the expansion. Skip whitespace.
while (p < args.size() && isspace(args[p])) {
p++;
}
save_expansion(_expansion, args.substr(p), parameter_names);
}
/**
* Creates a custom manifest definition, for example as specified from a
* command-line -D option.
*/
CPPManifest::
CPPManifest(const CPPPreprocessor &parser, const string &macro, const string &definition) :
_parser(parser),
_variadic_param(-1),
_expr(nullptr),
_vis(V_public)
{
_loc.first_line = 0;
_loc.first_column = 0;
_loc.last_line = 0;
_loc.last_column = 0;
assert(!macro.empty());
assert(!isspace(macro[0]));
// First, identify the manifest name.
size_t p = 0;
while (p < macro.size() && !isspace(macro[p]) && macro[p] != '(') {
p++;
}
_name = macro.substr(0, p);
vector_string parameter_names;
if (macro[p] == '(') {
// Hmm, parameters.
_has_parameters = true;
parse_parameters(macro, p, parameter_names);
_num_parameters = parameter_names.size();
p++;
} else {
_has_parameters = false;
_num_parameters = 0;
}
save_expansion(_expansion, definition, parameter_names);
}
/**
*
*/
CPPManifest::
~CPPManifest() {
delete _expr;
}
/**
* This implements the stringification operator, #.
*/
string CPPManifest::
stringify(const string &source) {
string result("\"");
enum {
S_escaped = 0x01,
S_single_quoted = 0x02,
S_double_quoted = 0x04,
S_quoted = 0x06,
};
int state = 0;
string::const_iterator it;
for (it = source.begin(); it != source.end(); ++it) {
char c = *it;
if ((state & S_escaped) == 0) {
switch (c) {
case '\\':
if (state & S_quoted) {
state |= S_escaped;
result += '\\';
}
break;
case '\'':
state ^= S_single_quoted;
break;
case '"':
state ^= S_double_quoted;
result += '\\';
break;
}
} else {
if (c == '\\' || c == '"') {
result += '\\';
}
state &= ~S_escaped;
}
result += c;
}
result += '"';
return result;
}
/**
*
*/
void CPPManifest::
extract_args(vector_string &args, const string &expr, size_t &p) const {
// Skip whitespace till paren.
while (p < expr.size() && isspace(expr[p])) {
p++;
}
if (p >= expr.size() || expr[p] != '(') {
// No paren, so we have only one arg.
size_t q = p;
while (p < expr.size() && (isalnum(expr[p]) || expr[p] == '_')) {
p++;
}
args.push_back(expr.substr(q, p - q));
}
else if (expr[p] == '"' || expr[p] == '\'') {
// Quoted string or character.
int quote_mark = expr[p];
p++;
while (p < expr.size() && expr[p] != quote_mark && expr[p] != '\n') {
if (expr[p] == '\\') {
p++;
}
if (p < expr.size()) {
p++;
}
}
p++;
}
else {
// Skip paren.
p++;
int paren_level = 1;
size_t q = p;
while (p < expr.size()) {
if (expr[p] == ',' && paren_level == 1) {
// Back up to strip any trailing whitespace.
size_t r = p;
while (r > q && isspace(expr[r - 1])) {
--r;
}
args.push_back(expr.substr(q, r - q));
q = p+1;
}
else if (expr[p] == '"' || expr[p] == '\'') {
// Quoted string or character.
int quote_mark = expr[p];
p++;
while (p < expr.size() && expr[p] != quote_mark && expr[p] != '\n') {
if (expr[p] == '\\') {
p++;
}
if (p < expr.size()) {
p++;
}
}
}
else if (expr[p] == '(') {
++paren_level;
}
else if (expr[p] == ')') {
--paren_level;
if (paren_level == 0) {
break;
}
}
else if (isspace(expr[p])) {
// Skip whitespace at the beginning.
if (q == p) {
q++;
}
}
p++;
}
{
// Back up to strip any trailing whitespace.
size_t r = p;
while (r > q && isspace(expr[r - 1])) {
--r;
}
if (!args.empty() || r > q) {
args.push_back(expr.substr(q, r - q));
}
}
if (p < expr.size() && expr[p] == ')') {
p++;
}
}
if ((int)args.size() < _num_parameters) {
_parser.warning("Not enough arguments for manifest " + _name);
}
else if (_variadic_param < 0 && (int)args.size() > _num_parameters) {
_parser.warning("Too many arguments for manifest " + _name);
}
}
/**
*
*/
string CPPManifest::
expand(const vector_string &args, bool expand_undefined, const Ignores &ignores) const {
return r_expand(_expansion, args, expand_undefined, ignores);
}
/**
* Returns the type of the manifest, if it is known, or NULL if the type
* cannot be determined.
*/
CPPType *CPPManifest::
determine_type() const {
if (_expr != nullptr) {
return _expr->determine_type();
}
return nullptr;
}
/**
* Returns true if the macro definitions are equal.
*/
bool CPPManifest::
is_equal(const CPPManifest *other) const {
if (this == other) {
return true;
}
if (_name != other->_name) {
return false;
}
if (_has_parameters != other->_has_parameters) {
return false;
}
if (_num_parameters != other->_num_parameters) {
return false;
}
if (_variadic_param != other->_variadic_param) {
return false;
}
if (_expansion != other->_expansion) {
return false;
}
return true;
}
/**
*
*/
void CPPManifest::
output(std::ostream &out) const {
out << _name;
if (_has_parameters) {
out << "(";
if (_num_parameters > 0) {
if (_variadic_param == 0) {
out << "...";
} else {
out << "$1";
}
for (size_t i = 1; i < _num_parameters; ++i) {
if (_variadic_param == (int)i) {
out << ", ...";
} else {
out << ", $" << i + 1;
}
}
}
out << ")";
}
Expansion::const_iterator ei;
for (ei = _expansion.begin(); ei != _expansion.end(); ++ei) {
if ((*ei)._paste) {
out << " ## ";
} else {
out << " ";
}
if ((*ei)._stringify) {
out << "#";
}
if ((*ei)._parm_number >= 0) {
if ((*ei)._parm_number == _variadic_param) {
out << "__VA_ARGS__";
} else {
out << "$" << (*ei)._parm_number + 1;
}
}
if ((*ei)._optional) {
out << "__VA_OPT__(";
}
if (!(*ei)._str.empty()) {
out << (*ei)._str;
}
if ((*ei)._optional) {
out << ")";
}
}
}
/**
*
*/
void CPPManifest::
parse_parameters(const string &args, size_t &p,
vector_string &parameter_names) {
assert(p < args.size());
assert(args[p] == '(');
p++;
while (p < args.size() && isspace(args[p])) {
p++;
}
while (p < args.size() && args[p] != ')') {
// Here's the beginning of a parm.
size_t q = p;
while (p < args.size() && !isspace(args[p]) &&
args[p] != ')' && args[p] != ',') {
p++;
}
// Check if it's a variadic parameter by checking if it ends with "...".
// This picks up both C99-style variadic macros and GCC-style variadic
// macros.
if (p - q >= 3 && args.compare(p - 3, 3, "...") == 0) {
_variadic_param = parameter_names.size();
parameter_names.push_back(args.substr(q, p - q - 3));
} else {
parameter_names.push_back(args.substr(q, p - q));
}
// Skip whitespace after the parameter name.
while (p < args.size() && isspace(args[p])) {
p++;
}
if (p < args.size() && args[p] == ',') {
p++;
// Skip whitespace after a comma.
while (p < args.size() && isspace(args[p])) {
p++;
}
}
}
}
/**
*
*/
void CPPManifest::
save_expansion(Expansion &expansion, const string &exp, const vector_string &parameter_names) {
// Walk through the expansion string. For each substring that is an
// identifier, check it against parameter_names.
size_t p = 0;
size_t last = 0;
bool stringify = false;
bool paste = false;
while (p < exp.size()) {
if (isalpha(exp[p]) || exp[p] == '_') {
// Here's the start of an identifier. Find the end of it.
size_t q = p;
p++;
while (p < exp.size() && (isalnum(exp[p]) || exp[p] == '_')) {
p++;
}
string ident = exp.substr(q, p - q);
// Is this identifier one of our parameters?
int pnum = -1;
if (ident == "__VA_ARGS__") {
// C99-style variadics, ie. #define macro(...) __VA_ARGS__
pnum = _variadic_param;
} else if (ident == "__VA_OPT__") {
// Optional expansion, only expands if __VA_ARGS__ is non-empty
while (p < exp.size() && isspace(exp[p])) {
++p;
}
if (p < exp.size() && exp[p] == '(') {
int start = ++p;
int nesting = 1;
while (p < exp.size() && nesting > 0) {
if (exp[p] == '(') {
++nesting;
}
else if (exp[p] == ')') {
--nesting;
}
++p;
}
if (last != q) {
expansion.push_back(ExpansionNode(exp.substr(last, q - last), paste));
paste = false;
}
// Store this as a nested expansion, because the whole thing may be
// stringified as a whole.
Expansion nested;
save_expansion(nested, exp.substr(start, p - 1 - start), parameter_names);
expansion.push_back(ExpansionNode(std::move(nested), stringify, paste, true));
stringify = false;
paste = false;
last = p;
continue;
}
} else {
for (int i = 0; pnum == -1 && i < (int)parameter_names.size(); ++i) {
const string &pname = parameter_names[i];
if (pname == ident) {
pnum = i;
}
}
}
if (pnum != -1) {
// Yep!
if (last != q) {
expansion.push_back(ExpansionNode(exp.substr(last, q - last), paste));
paste = false;
}
expansion.push_back(ExpansionNode(pnum, stringify, paste));
stringify = false;
paste = false;
last = p;
}
} else if (exp[p] == '#') {
// This may be a stringification operator.
if (last != p) {
expansion.push_back(ExpansionNode(exp.substr(last, p - last), paste));
paste = false;
}
++p;
if (p < exp.size() && exp[p] == '#') {
// Woah, this is a token-pasting operator.
paste = true;
if (!expansion.empty()) {
// The previous expansion shouldn't be expanded.
expansion.back()._expand = false;
}
++p;
} else {
// Mark that the next argument should be stringified.
stringify = true;
}
last = p;
} else if (isspace(exp[p])) {
if (last != p) {
expansion.push_back(ExpansionNode(exp.substr(last, p - last), paste));
paste = false;
}
++p;
last = p;
} else {
++p;
}
}
if (last != p) {
expansion.push_back(ExpansionNode(exp.substr(last, p - last), paste));
}
}
/**
*
*/
string CPPManifest::
r_expand(const Expansion &expansion, const vector_string &args,
bool expand_undefined, const Ignores &ignores) const {
std::string result;
for (const ExpansionNode &node : expansion) {
if (node._parm_number >= 0) {
int i = node._parm_number;
string subst;
if (i < (int)args.size()) {
subst = args[i];
if (i == _variadic_param) {
for (++i; i < (int)args.size(); ++i) {
subst += ", " + args[i];
}
}
if (node._stringify) {
subst = stringify(subst);
}
}
else if (i == _variadic_param && node._paste) {
// Special case GCC behavior: if __VA_ARGS__ is pasted to a comma and
// no arguments are passed, the comma is removed. MSVC does this
// automatically. Not sure if we should allow MSVC behavior as well.
if (!result.empty() && *result.rbegin() == ',') {
result.resize(result.size() - 1);
}
}
if (node._expand) {
_parser.expand_manifests(subst, expand_undefined, ignores);
}
if (!subst.empty()) {
if (result.empty() || node._paste || result.back() == '(') {
result += subst;
} else {
result += ' ';
result += subst;
}
}
}
if (!node._str.empty()) {
if (result.empty() || node._paste || node._str[0] == ',' || node._str[0] == ')') {
result += node._str;
} else {
result += ' ';
result += node._str;
}
}
if (!node._nested.empty()) {
string nested_result;
if (node._optional && args.size() >= _num_parameters) {
nested_result = r_expand(node._nested, args, expand_undefined, ignores);
}
if (node._stringify) {
nested_result = stringify(nested_result);
}
if (result.empty() || node._paste) {
result += nested_result;
} else {
result += ' ';
result += nested_result;
}
}
}
return result;
}

View File

@ -1,100 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppManifest.h
* @author drose
* @date 1999-10-22
*/
#ifndef CPPMANIFEST_H
#define CPPMANIFEST_H
#include "dtoolbase.h"
#include "cppFile.h"
#include "cppVisibility.h"
#include "cppBisonDefs.h"
#include "vector_string.h"
#include <unordered_set>
class CPPExpression;
class CPPType;
/**
*
*/
class CPPManifest {
public:
typedef std::unordered_set<const CPPManifest *> Ignores;
CPPManifest(const CPPPreprocessor &parser, const std::string &args, const cppyyltype &loc);
CPPManifest(const CPPPreprocessor &parser, const std::string &macro, const std::string &definition);
~CPPManifest();
static std::string stringify(const std::string &source);
void extract_args(vector_string &args, const std::string &expr, size_t &p) const;
std::string expand(const vector_string &args = vector_string(),
bool expand_undefined = false,
const Ignores &ignores = Ignores()) const;
CPPType *determine_type() const;
bool is_equal(const CPPManifest *other) const;
void output(std::ostream &out) const;
const CPPPreprocessor &_parser;
std::string _name;
bool _has_parameters;
size_t _num_parameters;
int _variadic_param;
cppyyltype _loc;
CPPExpression *_expr;
// Manifests don't have a visibility in the normal sense. Normally this
// will be V_public. But a manifest that is defined between __begin_publish
// and __end_publish will have a visibility of V_published.
CPPVisibility _vis;
private:
class ExpansionNode {
public:
ExpansionNode(int parm_number, bool stringify, bool paste);
ExpansionNode(const std::string &str, bool paste = false);
ExpansionNode(std::vector<ExpansionNode> nested, bool stringify = false, bool paste = false, bool optional = false);
bool operator ==(const ExpansionNode &other) const;
int _parm_number;
bool _expand;
bool _stringify;
bool _paste;
bool _optional;
std::string _str;
std::vector<ExpansionNode> _nested;
};
typedef std::vector<ExpansionNode> Expansion;
void parse_parameters(const std::string &args, size_t &p,
vector_string &parameter_names);
void save_expansion(Expansion &expansion, const std::string &exp,
const vector_string &parameter_names);
std::string r_expand(const Expansion &expansion, const vector_string &args,
bool expand_undefined, const Ignores &ignores) const;
Expansion _expansion;
};
inline std::ostream &operator << (std::ostream &out, const CPPManifest &manifest) {
manifest.output(out);
return out;
}
#endif

View File

@ -1,167 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppNameComponent.cxx
* @author drose
* @date 1999-11-12
*/
#include "cppNameComponent.h"
#include "cppTemplateParameterList.h"
using std::string;
/**
*
*/
CPPNameComponent::
CPPNameComponent(const string &name) :
_name(name)
{
_templ = nullptr;
}
/**
*
*/
bool CPPNameComponent::
operator == (const CPPNameComponent &other) const {
if (_name != other._name) {
return false;
}
if (_templ == nullptr && other._templ == nullptr) {
return true;
}
if (_templ == nullptr || other._templ == nullptr) {
return false;
}
if (*_templ != *other._templ) {
return false;
}
return true;
}
/**
*
*/
bool CPPNameComponent::
operator != (const CPPNameComponent &other) const {
return !(*this == other);
}
/**
*
*/
bool CPPNameComponent::
operator < (const CPPNameComponent &other) const {
if (_name != other._name) {
return _name < other._name;
}
if (_templ == nullptr && other._templ == nullptr) {
return false;
}
if (_templ == nullptr || other._templ == nullptr) {
return _templ < other._templ;
}
return (*_templ) < (*other._templ);
}
/**
*
*/
string CPPNameComponent::
get_name() const {
return _name;
}
/**
*
*/
string CPPNameComponent::
get_name_with_templ(CPPScope *scope) const {
std::ostringstream strm;
strm << _name;
if (_templ != nullptr) {
strm << "< ";
_templ->output(strm, scope);
strm << " >";
}
return strm.str();
}
/**
*
*/
CPPTemplateParameterList *CPPNameComponent::
get_templ() const {
return _templ;
}
/**
*
*/
bool CPPNameComponent::
empty() const {
return _name.empty();
}
/**
*
*/
bool CPPNameComponent::
has_templ() const {
return _templ != nullptr;
}
/**
* Returns true if the name component includes a template parameter list that
* includes some not-yet-defined type.
*/
bool CPPNameComponent::
is_tbd() const {
if (_templ != nullptr) {
return _templ->is_tbd();
}
return false;
}
/**
*
*/
void CPPNameComponent::
set_name(const string &name) {
_name = name;
}
/**
*
*/
void CPPNameComponent::
append_name(const string &name) {
_name += name;
}
/**
*
*/
void CPPNameComponent::
set_templ(CPPTemplateParameterList *templ) {
_templ = templ;
}
/**
*
*/
void CPPNameComponent::
output(std::ostream &out) const {
out << _name;
if (_templ != nullptr) {
out << "< " << *_templ << " >";
}
}

View File

@ -1,56 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppNameComponent.h
* @author drose
* @date 1999-11-12
*/
#ifndef CPPNAMECOMPONENT_H
#define CPPNAMECOMPONENT_H
#include "dtoolbase.h"
#include "cppBisonDefs.h"
#include <string>
class CPPTemplateParameterList;
class CPPScope;
class CPPNameComponent {
public:
CPPNameComponent(const std::string &name);
bool operator == (const CPPNameComponent &other) const;
bool operator != (const CPPNameComponent &other) const;
bool operator < (const CPPNameComponent &other) const;
std::string get_name() const;
std::string get_name_with_templ(CPPScope *scope = nullptr) const;
CPPTemplateParameterList *get_templ() const;
bool empty() const;
bool has_templ() const;
bool is_tbd() const;
void set_name(const std::string &name);
void append_name(const std::string &name);
void set_templ(CPPTemplateParameterList *templ);
void output(std::ostream &out) const;
private:
std::string _name;
CPPTemplateParameterList *_templ;
};
inline std::ostream &operator << (std::ostream &out, const CPPNameComponent &name) {
name.output(out);
return out;
}
#endif

View File

@ -1,116 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppNamespace.cxx
* @author drose
* @date 1999-11-16
*/
#include "cppNamespace.h"
#include "cppIdentifier.h"
#include "cppScope.h"
#include "indent.h"
/**
*
*/
CPPNamespace::
CPPNamespace(CPPIdentifier *ident, CPPScope *scope, const CPPFile &file,
CPPAttributeList attr) :
CPPDeclaration(file, std::move(attr)),
_is_inline(false),
_ident(ident),
_scope(scope)
{
}
/**
*
*/
std::string CPPNamespace::
get_simple_name() const {
if (_ident == nullptr) {
return "";
}
return _ident->get_simple_name();
}
/**
*
*/
std::string CPPNamespace::
get_local_name(CPPScope *scope) const {
if (_ident == nullptr) {
return "";
}
return _ident->get_local_name(scope);
}
/**
*
*/
std::string CPPNamespace::
get_fully_scoped_name() const {
if (_ident == nullptr) {
return "";
}
return _ident->get_fully_scoped_name();
}
/**
*
*/
CPPScope *CPPNamespace::
get_scope() const {
return _scope;
}
/**
*
*/
void CPPNamespace::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
if (_is_inline) {
out << "inline ";
}
out << "namespace ";
if (!complete && _ident != nullptr) {
// If we have a name, use it.
out << "namespace " << _ident->get_local_name(scope);
}
else {
if (!_attributes.is_empty()) {
out << _attributes << " ";
}
if (_ident != nullptr) {
out << _ident->get_local_name(scope) << " {\n";
} else {
out << "{\n";
}
_scope->write(out, indent_level + 2, _scope);
indent(out, indent_level) << "}";
}
}
/**
*
*/
CPPDeclaration::SubType CPPNamespace::
get_subtype() const {
return ST_namespace;
}
/**
*
*/
CPPNamespace *CPPNamespace::
as_namespace() {
return this;
}

View File

@ -1,52 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppNamespace.h
* @author drose
* @date 1999-11-16
*/
#ifndef CPPNAMESPACE_H
#define CPPNAMESPACE_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
class CPPIdentifier;
class CPPScope;
/**
*
*/
class CPPNamespace : public CPPDeclaration {
public:
CPPNamespace(CPPIdentifier *ident, CPPScope *scope,
const CPPFile &file, CPPAttributeList attr = CPPAttributeList());
std::string get_simple_name() const;
std::string get_local_name(CPPScope *scope = nullptr) const;
std::string get_fully_scoped_name() const;
CPPScope *get_scope() const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPNamespace *as_namespace();
// We can't call this _inline since that would clash with an MSVC built-in
// keyword declaration.
bool _is_inline;
private:
CPPIdentifier *_ident;
CPPScope *_scope;
};
#endif

View File

@ -1,239 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppParameterList.cxx
* @author drose
* @date 1999-10-21
*/
#include "cppParameterList.h"
#include "cppInstance.h"
/**
*
*/
CPPParameterList::
CPPParameterList() {
_includes_ellipsis = false;
}
/**
* This is similar to operator == except it is more forgiving: it is true if
* only the length and order of types is the same, never minding the instance
* names or initial values.
*/
bool CPPParameterList::
is_equivalent(const CPPParameterList &other) const {
if (_includes_ellipsis != other._includes_ellipsis) {
return false;
}
if (_parameters.size() != other._parameters.size()) {
return false;
}
for (int i = 0; i < (int)_parameters.size(); ++i) {
if (!_parameters[i]->_type->is_equivalent(*other._parameters[i]->_type)) {
return false;
}
}
return true;
}
/**
*
*/
bool CPPParameterList::
operator == (const CPPParameterList &other) const {
if (_includes_ellipsis != other._includes_ellipsis) {
return false;
}
if (_parameters.size() != other._parameters.size()) {
return false;
}
for (int i = 0; i < (int)_parameters.size(); ++i) {
if (*_parameters[i] != *other._parameters[i]) {
return false;
}
}
return true;
}
/**
*
*/
bool CPPParameterList::
operator != (const CPPParameterList &other) const {
return !(*this == other);
}
/**
*
*/
bool CPPParameterList::
operator < (const CPPParameterList &other) const {
if (_includes_ellipsis != other._includes_ellipsis) {
return _includes_ellipsis < other._includes_ellipsis;
}
if (_parameters.size() != other._parameters.size()) {
return _parameters.size() < other._parameters.size();
}
for (int i = 0; i < (int)_parameters.size(); ++i) {
if (*_parameters[i] != *other._parameters[i]) {
return *_parameters[i] < *other._parameters[i];
}
}
return false;
}
/**
* Returns true if any of the types in the parameter list are base on
* CPPTBDType.
*/
bool CPPParameterList::
is_tbd() const {
for (int i = 0; i < (int)_parameters.size(); ++i) {
if (_parameters[i]->_type->is_tbd()) {
return true;
}
}
return false;
}
/**
* Returns true if any of the types in the parameter list turns out to be a
* constant expression, which is a clue that this parameter list is actually
* intended to be an instance declaration.
*/
bool CPPParameterList::
is_parameter_expr() const {
for (int i = 0; i < (int)_parameters.size(); ++i) {
if (_parameters[i]->_type->is_parameter_expr()) {
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
* has not yet been instantiated.
*/
bool CPPParameterList::
is_fully_specified() const {
for (int i = 0; i < (int)_parameters.size(); ++i) {
if (!_parameters[i]->is_fully_specified()) {
return false;
}
}
return true;
}
/**
*
*/
CPPParameterList *CPPParameterList::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
CPPParameterList *rep = new CPPParameterList;
bool any_changed = false;
for (int i = 0; i < (int)_parameters.size(); ++i) {
CPPInstance *inst =
_parameters[i]->substitute_decl(subst, current_scope, global_scope)
->as_instance();
if (inst != _parameters[i]) {
any_changed = true;
}
rep->_parameters.push_back(inst);
}
if (!any_changed) {
delete rep;
rep = this;
}
return rep;
}
/**
* Returns an equivalent CPPParameterList, in which all of the individual
* types have been resolved.
*/
CPPParameterList *CPPParameterList::
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
CPPParameterList *rep = new CPPParameterList;
bool any_changed = false;
for (int i = 0; i < (int)_parameters.size(); ++i) {
CPPInstance *inst = _parameters[i];
CPPType *new_type = inst->_type;
if (new_type->is_tbd()) {
new_type = new_type->resolve_type(current_scope, global_scope);
}
if (new_type != inst->_type) {
any_changed = true;
CPPInstance *new_inst = new CPPInstance(*inst);
new_inst->_type = new_type;
rep->_parameters.push_back(new_inst);
} else {
rep->_parameters.push_back(inst);
}
}
if (!any_changed) {
delete rep;
rep = this;
}
return rep;
}
/**
* If num_default_parameters is >= 0, it indicates the number of default
* parameter values to show on output. Otherwise, all parameter values are
* shown.
*/
void CPPParameterList::
output(std::ostream &out, CPPScope *scope, bool parameter_names,
int num_default_parameters) const {
if (!_parameters.empty()) {
for (int i = 0; i < (int)_parameters.size(); ++i) {
if (i != 0) {
out << ", ";
}
// Save the default value expression; we might be about to temporarily
// clear it.
CPPExpression *expr = _parameters[i]->_initializer;
if (num_default_parameters >= 0 &&
i < (int)_parameters.size() - num_default_parameters) {
// Don't show the default value for this parameter.
_parameters[i]->_initializer = nullptr;
}
if (parameter_names) {
_parameters[i]->output(out, 0, scope, false);
} else {
_parameters[i]->_type->output(out, 0, scope, false);
}
// Restore the default value expression.
_parameters[i]->_initializer = expr;
}
if (_includes_ellipsis) {
out << ", ...";
}
} else if (_includes_ellipsis) {
out << "...";
} else {
// No parameters.
out << "void";
}
}

View File

@ -1,66 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppParameterList.h
* @author drose
* @date 1999-10-21
*/
#ifndef CPPPARAMETERLIST_H
#define CPPPARAMETERLIST_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
#include <vector>
class CPPInstance;
class CPPScope;
/**
* A list of formal parameters for a function declaration.
*/
class CPPParameterList {
public:
CPPParameterList();
bool is_equivalent(const CPPParameterList &other) const;
bool operator == (const CPPParameterList &other) const;
bool operator != (const CPPParameterList &other) const;
bool operator < (const CPPParameterList &other) const;
bool is_tbd() const;
bool is_parameter_expr() const;
bool is_fully_specified() const;
CPPParameterList *substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
CPPParameterList *resolve_type(CPPScope *current_scope,
CPPScope *global_scope);
// This vector contains a list of formal parameters, in order. A parameter
// may have an empty identifer name.
typedef std::vector<CPPInstance *> Parameters;
Parameters _parameters;
bool _includes_ellipsis;
void output(std::ostream &out, CPPScope *scope, bool parameter_names,
int num_default_parameters = -1) const;
};
inline std::ostream &
operator << (std::ostream &out, const CPPParameterList &plist) {
plist.output(out, nullptr, true);
return out;
}
#endif

View File

@ -1,93 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppParser.cxx
* @author drose
* @date 1999-10-19
*/
#include "cppParser.h"
#include "cppFile.h"
#include "cppTypeParser.h"
#include "cppBisonDefs.h"
#include <set>
#include <assert.h>
bool cppparser_output_class_keyword = false;
/**
*
*/
CPPParser::
CPPParser() : CPPScope(nullptr, CPPNameComponent(""), V_public) {
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which
* has not yet been instantiated.
*/
bool CPPParser::
is_fully_specified() const {
// The global scope is always considered to be "fully specified", even if it
// contains some template declarations.
return true;
}
/**
*
*/
bool CPPParser::
parse_file(const Filename &filename) {
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)) {
std::cerr << "Unable to read " << filename << "\n";
return false;
}
parse_cpp(this);
return get_error_count() == 0;
}
/**
* Given a string, expand all manifests within the string and evaluate it as
* an expression. Returns NULL if the string is not a valid expression.
*/
CPPExpression *CPPParser::
parse_expr(const std::string &expr) {
YYLTYPE loc = {};
return CPPPreprocessor::parse_expr(expr, this, this, loc);
}
/**
* Given a string, interpret it as a type name and return the corresponding
* CPPType. Returns NULL if the string is not a valid type.
*/
CPPType *CPPParser::
parse_type(const std::string &type) {
CPPTypeParser ep(this, this);
ep._verbose = 0;
if (ep.parse_type(type, *this)) {
return ep._type;
} else {
return nullptr;
}
}

View File

@ -1,52 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppParser.h
* @author drose
* @date 1999-10-19
*/
#ifndef CPPPARSER_H
#define CPPPARSER_H
#include "dtoolbase.h"
#include "cppScope.h"
#include "cppPreprocessor.h"
#include "filename.h"
#include <set>
/**
*
*/
class CPPParser : public CPPScope, public CPPPreprocessor {
public:
CPPParser();
virtual bool is_fully_specified() const;
bool parse_file(const Filename &filename);
CPPExpression *parse_expr(const std::string &expr);
CPPType *parse_type(const std::string &type);
};
/*
* Normally, this variable should be left true, especially while parsing.
* However, after parsing has finished, and you want to output the results of
* parsing in a way that can be successfully compiled by VC++, you may need to
* set this variable to false. It controls the way typenames are written.
* When true, class names are written 'class X', which is the way the parser
* expects things to come, and which compiles successfully under every
* compiler except VC++. When false, class names are written simply 'X',
* which is the only way they'll compile under VC++.
*/
extern bool cppparser_output_class_keyword;
#endif

View File

@ -1,308 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppPointerType.cxx
* @author drose
* @date 1999-10-19
*/
#include "cppPointerType.h"
#include "cppFunctionType.h"
#include "cppIdentifier.h"
#include "cppArrayType.h"
#include "cppStructType.h"
#include "cppSimpleType.h"
/**
*
*/
CPPPointerType::
CPPPointerType(CPPType *pointing_at) :
CPPType(CPPFile()),
_pointing_at(pointing_at)
{
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which
* has not yet been instantiated.
*/
bool CPPPointerType::
is_fully_specified() const {
return CPPType::is_fully_specified() &&
_pointing_at->is_fully_specified();
}
/**
*
*/
CPPDeclaration *CPPPointerType::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
SubstDecl::const_iterator si = subst.find(this);
if (si != subst.end()) {
return (*si).second;
}
CPPPointerType *rep = new CPPPointerType(*this);
rep->_pointing_at =
_pointing_at->substitute_decl(subst, current_scope, global_scope)
->as_type();
if (rep->_pointing_at == _pointing_at) {
delete rep;
rep = this;
}
rep = CPPType::new_type(rep)->as_pointer_type();
subst.insert(SubstDecl::value_type(this, rep));
return rep;
}
/**
* If this CPPType object is a forward reference or other nonspecified
* reference to a type that might now be known a real type, returns the real
* type. Otherwise returns the type itself.
*/
CPPType *CPPPointerType::
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
CPPType *ptype = _pointing_at->resolve_type(current_scope, global_scope);
if (ptype != _pointing_at) {
CPPPointerType *rep = new CPPPointerType(*this);
rep->_pointing_at = ptype;
return CPPType::new_type(rep);
}
return this;
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPPointerType::
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.
*/
bool CPPPointerType::
is_trivial() const {
return true;
}
/**
* Returns true if the type can be safely copied by memcpy or memmove.
*/
bool CPPPointerType::
is_trivially_copyable() 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 != nullptr) {
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 != nullptr && b_struct != nullptr) {
return a_struct->is_base_of(b_struct);
}
return false;
}
/**
* Returns true if the type is default-constructible.
*/
bool CPPPointerType::
is_default_constructible() const {
return true;
}
/**
* Returns true if the type is copy-constructible.
*/
bool CPPPointerType::
is_copy_constructible() const {
return true;
}
/**
* Returns true if the type is copy-assignable.
*/
bool CPPPointerType::
is_copy_assignable() const {
return true;
}
/**
* 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
* different pointers or somewhat different definitions. It's useful for
* parameter matching, etc.
*/
bool CPPPointerType::
is_equivalent(const CPPType &other) const {
const CPPPointerType *ot = ((CPPType *)&other)->as_pointer_type();
if (ot == nullptr) {
return CPPType::is_equivalent(other);
}
return _pointing_at->is_equivalent(*ot->_pointing_at);
}
/**
*
*/
void CPPPointerType::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
/*
CPPFunctionType *ftype = _pointing_at->as_function_type();
if (ftype != (CPPFunctionType *)NULL) {
// Pointers to functions are a bit of a special case; we have to be a
// little more careful about where the '*' goes.
string star = "*";
if ((ftype->_flags & CPPFunctionType::F_method_pointer) != 0) {
// We have to output pointers-to-method with a scoping before the '*'.
star = ftype->_class_owner->get_fully_scoped_name() + "::*";
}
_pointing_at->output_instance(out, indent_level, scope, complete,
star, "");
} else {
_pointing_at->output(out, indent_level, scope, complete);
out << " *";
}
*/
output_instance(out, indent_level, scope, complete, "", "");
}
/**
* Formats a C++-looking line that defines an instance of the given type, with
* the indicated name. In most cases this will be "type name", but some types
* have special exceptions.
*/
void CPPPointerType::
output_instance(std::ostream &out, int indent_level, CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const {
std::string star = "*";
CPPFunctionType *ftype = _pointing_at->as_function_type();
if (ftype != nullptr &&
((ftype->_flags & CPPFunctionType::F_method_pointer) != 0)) {
// We have to output pointers-to-method with a scoping before the '*'.
star = ftype->_class_owner->get_fully_scoped_name() + "::*";
}
if (!_attributes.is_empty()) {
std::ostringstream strm;
strm << star << _attributes << " ";
star = strm.str();
}
_pointing_at->output_instance(out, indent_level, scope, complete,
star + prename, name);
}
/**
*
*/
CPPDeclaration::SubType CPPPointerType::
get_subtype() const {
return ST_pointer;
}
/**
*
*/
CPPPointerType *CPPPointerType::
as_pointer_type() {
return this;
}
/**
* Called by CPPDeclaration() to determine whether this type is equivalent to
* another type of the same type.
*/
bool CPPPointerType::
is_equal(const CPPDeclaration *other) const {
const CPPPointerType *ot = ((CPPDeclaration *)other)->as_pointer_type();
assert(ot != nullptr);
return _pointing_at == ot->_pointing_at;
}
/**
* Called by CPPDeclaration() to determine whether this type should be ordered
* before another type of the same type, in an arbitrary but fixed ordering.
*/
bool CPPPointerType::
is_less(const CPPDeclaration *other) const {
const CPPPointerType *ot = ((CPPDeclaration *)other)->as_pointer_type();
assert(ot != nullptr);
return _pointing_at < ot->_pointing_at;
}

View File

@ -1,64 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppPointerType.h
* @author drose
* @date 1999-10-19
*/
#ifndef CPPPOINTERTYPE_H
#define CPPPOINTERTYPE_H
#include "dtoolbase.h"
#include "cppType.h"
/**
*
*/
class CPPPointerType : public CPPType {
public:
CPPPointerType(CPPType *pointing_at);
CPPType *_pointing_at;
virtual bool is_fully_specified() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
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_trivially_copyable() const;
virtual bool is_constructible(const CPPType *other) const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_copy_assignable() const;
virtual bool is_equivalent(const CPPType &other) const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual void output_instance(std::ostream &out, int indent_level,
CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const;
virtual SubType get_subtype() const;
virtual CPPPointerType *as_pointer_type();
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,235 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppPreprocessor.h
* @author drose
* @date 1999-10-22
*/
#ifndef CPPPREPROCESSOR_H
#define CPPPREPROCESSOR_H
#include "dtoolbase.h"
#include "cppManifest.h"
#include "cppToken.h"
#include "cppFile.h"
#include "cppCommentBlock.h"
#include "dSearchPath.h"
#include "vector_string.h"
#include <map>
#include <vector>
#include <unordered_map>
class CPPScope;
class CPPTemplateParameterList;
class CPPExpression;
// #define CPP_VERBOSE_LEX
/**
*
*/
class CPPPreprocessor {
public:
CPPPreprocessor();
bool preprocess_file(const Filename &filename);
void set_verbose(int verbose);
int get_verbose() const;
void copy_filepos(const CPPPreprocessor &other);
CPPFile get_file() const;
int get_line_number() const;
int get_col_number() const;
CPPToken get_next_token();
CPPToken peek_next_token();
#ifdef CPP_VERBOSE_LEX
CPPToken get_next_token0();
int _token_index;
#endif
void warning(const std::string &message) const;
void warning(const std::string &message, const YYLTYPE &loc) const;
void error(const std::string &message) const;
void error(const std::string &message, const YYLTYPE &loc) const;
void show_line(const YYLTYPE &loc) const;
CPPCommentBlock *get_comment_before(int line, CPPFile file);
CPPCommentBlock *get_comment_on(int line, CPPFile file);
int get_warning_count() const;
int get_error_count() const;
typedef std::unordered_map<std::string, CPPManifest *> Manifests;
Manifests _manifests;
typedef std::vector<CPPManifest *> ManifestStack;
std::map<std::string, ManifestStack> _manifest_stack;
std::vector<CPPFile::Source> _quote_include_kind;
DSearchPath _quote_include_path;
DSearchPath _angle_include_path;
bool _noangles;
CPPComments _comments;
typedef std::set<CPPFile> ParsedFiles;
ParsedFiles _parsed_files;
typedef std::set<std::string> Includes;
Includes _quote_includes;
Includes _angle_includes;
std::set<Filename> _explicit_files;
// This is normally true, to indicate that the preprocessor should decode
// identifiers like foo::bar<snarf> into a single IDENTIFIER,
// TYPENAME_IDENTIFIER, or SCOPING token for yacc's convenience. When
// false, it leaves them alone and returns a sequence of SIMPLE_IDENTIFIER
// and SCOPE tokens instead.
bool _resolve_identifiers;
// The default _verbose level is 1, which will output normal error and
// warning messages but nothing else. Set this to 0 to make the warning
// messages go away (although the counts will still be incremented), or set
// it higher to get more debugging information.
int _verbose;
// The location of the last token.
cppyyltype _last_token_loc;
protected:
bool init_cpp(const CPPFile &file);
bool init_const_expr(const std::string &expr);
bool init_type(const std::string &type);
bool push_file(const CPPFile &file);
bool push_string(const std::string &input);
bool push_expansion(const std::string &input, const CPPManifest *manifest,
const YYLTYPE &loc);
public:
void expand_manifests(std::string &expr, bool expand_undefined = false,
const CPPManifest::Ignores &ignores = CPPManifest::Ignores()) const;
CPPExpression *parse_expr(const std::string &expr, CPPScope *current_scope,
CPPScope *global_scope, const YYLTYPE &loc);
private:
CPPToken internal_get_next_token();
int check_digraph(int c);
int check_trigraph(int c);
int skip_whitespace(int c);
int skip_comment(int c);
int skip_c_comment(int c);
int skip_cpp_comment(int c);
int skip_digit_separator(int c);
int process_directive(int c);
int get_preprocessor_command(int c, std::string &command);
int get_preprocessor_args(int c, std::string &args);
void handle_define_directive(const std::string &args, const YYLTYPE &loc);
void handle_undef_directive(const std::string &args, const YYLTYPE &loc);
void handle_ifdef_directive(const std::string &args, const YYLTYPE &loc);
void handle_ifndef_directive(const std::string &args, const YYLTYPE &loc);
void handle_if_directive(const std::string &args, const YYLTYPE &loc);
void handle_include_directive(const std::string &args, const YYLTYPE &loc);
void handle_pragma_directive(const std::string &args, const YYLTYPE &loc);
void handle_error_directive(const std::string &args, const YYLTYPE &loc);
void skip_false_if_block(bool consider_elifs);
bool is_manifest_defined(const std::string &manifest_name) const;
bool find_include(Filename &filename, bool angle_quotes, CPPFile::Source &source) const;
CPPToken get_quoted_char(int c);
CPPToken get_quoted_string(int c);
CPPToken get_identifier(int c);
CPPToken get_literal(int token, YYLTYPE loc, const std::string &str,
const YYSTYPE &result = YYSTYPE());
CPPToken expand_manifest(const CPPManifest *manifest, const YYLTYPE &loc);
void r_expand_manifests(std::string &expr, bool expand_undefined,
const YYLTYPE &loc, std::set<const CPPManifest *> &expanded);
void extract_manifest_args(const std::string &name, int num_args,
int va_arg, vector_string &args);
void expand_defined_function(std::string &expr, size_t q, size_t &p) const;
void expand_has_include_function(std::string &expr, size_t q, size_t &p) const;
CPPToken get_number(int c);
int scan_escape_sequence(int c);
std::string scan_quoted(int c);
std::string scan_raw(int c);
bool should_ignore_manifest(const CPPManifest *manifest) const;
bool should_ignore_preprocessor() const;
int get();
int peek();
void unget(int c);
CPPTemplateParameterList *
nested_parse_template_instantiation(CPPTemplateScope *scope);
void skip_to_end_nested();
void skip_to_angle_bracket();
int get_file_depth() const;
class InputFile {
public:
InputFile();
~InputFile();
bool open(const CPPFile &file);
bool connect_input(const std::string &input);
int get();
int peek();
const CPPManifest *_manifest;
CPPFile _file;
std::string _input;
std::istream *_in;
int _line_number;
int _col_number;
int _next_line_number;
int _next_col_number;
bool _lock_position;
bool _ignore_manifest;
int _prev_last_c;
InputFile *_parent = nullptr;
};
InputFile *_infile = nullptr;
enum State {
S_normal, S_eof, S_nested, S_end_nested
};
State _state;
int _paren_nesting;
bool _parsing_template_params;
bool _parsing_attribute;
bool _start_of_line;
int _unget;
int _last_c;
bool _last_cpp_comment;
bool _save_comments;
std::vector<CPPToken> _saved_tokens;
mutable int _warning_count;
mutable int _error_count;
bool _error_abort;
};
#endif

View File

@ -1,296 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppReferenceType.cxx
* @author drose
* @date 1999-10-19
*/
#include "cppReferenceType.h"
#include "cppTypedefType.h"
#include "cppStructType.h"
/**
*
*/
CPPReferenceType::
CPPReferenceType(CPPType *pointing_at, ValueCategory vcat) :
CPPType(CPPFile()),
_pointing_at(pointing_at),
_value_category(vcat)
{
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which
* has not yet been instantiated.
*/
bool CPPReferenceType::
is_fully_specified() const {
return CPPType::is_fully_specified() &&
_pointing_at->is_fully_specified();
}
/**
*
*/
CPPDeclaration *CPPReferenceType::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
SubstDecl::const_iterator si = subst.find(this);
if (si != subst.end()) {
return (*si).second;
}
CPPReferenceType *rep = new CPPReferenceType(*this);
rep->_pointing_at =
_pointing_at->substitute_decl(subst, current_scope, global_scope)
->as_type();
if (rep->_pointing_at == _pointing_at) {
delete rep;
rep = this;
}
rep = CPPType::new_type(rep)->as_reference_type();
subst.insert(SubstDecl::value_type(this, rep));
return rep;
}
/**
* If this CPPType object is a forward reference or other nonspecified
* reference to a type that might now be known a real type, returns the real
* type. Otherwise returns the type itself.
*/
CPPType *CPPReferenceType::
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
CPPType *ptype = _pointing_at->resolve_type(current_scope, global_scope);
if (ptype != _pointing_at) {
CPPReferenceType *rep = new CPPReferenceType(*this);
rep->_pointing_at = ptype;
return CPPType::new_type(rep);
}
return this;
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPReferenceType::
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.
*/
bool CPPReferenceType::
is_trivial() const {
return false;
}
/**
* Returns true if the type can be safely copied by memcpy or memmove.
*/
bool CPPReferenceType::
is_trivially_copyable() 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 != nullptr) {
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 != nullptr && b_struct != nullptr) {
return a_struct->is_base_of(b_struct);
}
return false;
}
/**
* Returns true if the type is default-constructible.
*/
bool CPPReferenceType::
is_default_constructible() const {
return false;
}
/**
* Returns true if the type is copy-constructible.
*/
bool CPPReferenceType::
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
* different pointers or somewhat different definitions. It's useful for
* parameter matching, etc.
*/
bool CPPReferenceType::
is_equivalent(const CPPType &other) const {
const CPPReferenceType *ot = ((CPPType *)&other)->as_reference_type();
if (ot == nullptr) {
return CPPType::is_equivalent(other);
}
return _pointing_at->is_equivalent(*ot->_pointing_at);
}
/**
*
*/
void CPPReferenceType::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
/*
_pointing_at->output(out, indent_level, scope, complete);
out << " &";
*/
output_instance(out, indent_level, scope, complete, "", "");
}
/**
* Formats a C++-looking line that defines an instance of the given type, with
* the indicated name. In most cases this will be "type name", but some types
* have special exceptions.
*/
void CPPReferenceType::
output_instance(std::ostream &out, int indent_level, CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const {
std::string prefix((_value_category == VC_rvalue) ? "&&" : "&");
if (!_attributes.is_empty()) {
std::ostringstream strm;
strm << prefix << _attributes << " ";
prefix = strm.str();
}
_pointing_at->output_instance(out, indent_level, scope, complete,
prefix + prename, name);
}
/**
*
*/
CPPDeclaration::SubType CPPReferenceType::
get_subtype() const {
return ST_reference;
}
/**
*
*/
CPPReferenceType *CPPReferenceType::
as_reference_type() {
return this;
}
/**
* Called by CPPDeclaration() to determine whether this type is equivalent to
* another type of the same type.
*/
bool CPPReferenceType::
is_equal(const CPPDeclaration *other) const {
const CPPReferenceType *ot = ((CPPDeclaration *)other)->as_reference_type();
assert(ot != nullptr);
return (_pointing_at == ot->_pointing_at) &&
(_value_category == ot->_value_category);
}
/**
* Called by CPPDeclaration() to determine whether this type should be ordered
* before another type of the same type, in an arbitrary but fixed ordering.
*/
bool CPPReferenceType::
is_less(const CPPDeclaration *other) const {
const CPPReferenceType *ot = ((CPPDeclaration *)other)->as_reference_type();
assert(ot != nullptr);
if (_value_category != ot->_value_category) {
return (_value_category < ot->_value_category);
}
return _pointing_at < ot->_pointing_at;
}

View File

@ -1,70 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppReferenceType.h
* @author drose
* @date 1999-10-19
*/
#ifndef CPPREFERENCETYPE_H
#define CPPREFERENCETYPE_H
#include "dtoolbase.h"
#include "cppType.h"
/**
* Either an lvalue- or rvalue-reference.
*/
class CPPReferenceType : public CPPType {
public:
enum ValueCategory {
VC_lvalue,
VC_rvalue
};
CPPReferenceType(CPPType *pointing_at, ValueCategory vcat=VC_lvalue);
CPPType *_pointing_at;
ValueCategory _value_category;
virtual bool is_fully_specified() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
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_trivially_copyable() 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(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual void output_instance(std::ostream &out, int indent_level,
CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const;
virtual SubType get_subtype() const;
virtual CPPReferenceType *as_reference_type();
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,165 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppScope.h
* @author drose
* @date 1999-10-21
*/
#ifndef CPPSCOPE_H
#define CPPSCOPE_H
#include "dtoolbase.h"
#include "cppVisibility.h"
#include "cppTemplateParameterList.h"
#include "cppNameComponent.h"
#include <vector>
#include <map>
#include <set>
#include <string>
class CPPType;
class CPPDeclaration;
class CPPExtensionType;
class CPPStructType;
class CPPNamespace;
class CPPUsing;
class CPPTypedefType;
class CPPInstance;
class CPPFunctionGroup;
class CPPTemplateScope;
class CPPTemplateParameterList;
class CPPPreprocessor;
class CPPNameComponent;
struct cppyyltype;
/**
*
*/
class CPPScope {
public:
CPPScope(CPPScope *parent_scope,
const CPPNameComponent &name, CPPVisibility starting_vis);
virtual ~CPPScope();
void set_current_vis(CPPVisibility current_vis);
CPPVisibility get_current_vis() const;
void set_struct_type(CPPStructType *struct_type);
CPPStructType *get_struct_type() const;
CPPScope *get_parent_scope() const;
virtual void add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
CPPPreprocessor *preprocessor,
const cppyyltype &pos);
virtual void add_enum_value(CPPInstance *inst);
virtual void define_typedef_type(CPPTypedefType *type,
CPPPreprocessor *error_sink = nullptr);
virtual void define_extension_type(CPPExtensionType *type,
CPPPreprocessor *error_sink = nullptr);
virtual void define_namespace(CPPNamespace *scope);
virtual void add_using(CPPUsing *using_decl, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr);
virtual bool is_fully_specified() const;
CPPScope *
instantiate(const CPPTemplateParameterList *actual_params,
CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
CPPScope *
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope) const;
CPPType *find_type(const std::string &name, bool recurse = true) const;
CPPType *find_type(const std::string &name,
CPPDeclaration::SubstDecl &subst,
CPPScope *global_scope,
bool recurse = true) const;
CPPScope *find_scope(const std::string &name, CPPScope *global_scope,
bool recurse = true) const;
CPPScope *find_scope(const std::string &name,
CPPDeclaration::SubstDecl &subst,
CPPScope *global_scope,
bool recurse = true) const;
CPPDeclaration *find_symbol(const std::string &name,
bool recurse = true) const;
CPPDeclaration *find_template(const std::string &name,
bool recurse = true) const;
virtual std::string get_simple_name() const;
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
virtual std::string get_fully_scoped_name() const;
virtual void output(std::ostream &out, CPPScope *scope) const;
void write(std::ostream &out, int indent, CPPScope *scope) const;
CPPTemplateScope *get_template_scope();
virtual CPPTemplateScope *as_template_scope();
private:
bool
copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst,
CPPScope *global_scope) const;
void handle_declaration(CPPDeclaration *decl, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr);
public:
typedef std::vector<CPPDeclaration *> Declarations;
Declarations _declarations;
typedef std::map<std::string, CPPType *> ExtensionTypes;
ExtensionTypes _structs;
ExtensionTypes _classes;
ExtensionTypes _unions;
ExtensionTypes _enums;
typedef std::map<std::string, CPPNamespace *> Namespaces;
Namespaces _namespaces;
typedef std::map<std::string, CPPType *> Types;
Types _types;
typedef std::map<std::string, CPPInstance *> Variables;
Variables _variables;
Variables _enum_values;
typedef std::map<std::string, CPPFunctionGroup *> Functions;
Functions _functions;
typedef std::map<std::string, CPPDeclaration *> Templates;
Templates _templates;
CPPNameComponent _name;
typedef std::set<CPPScope *> Using;
Using _using;
protected:
CPPScope *_parent_scope;
CPPStructType *_struct_type;
CPPVisibility _current_vis;
private:
typedef std::map<const CPPTemplateParameterList *, CPPScope *, CPPTPLCompare> Instantiations;
Instantiations _instantiations;
bool _is_fully_specified;
bool _fully_specified_known;
bool _is_fully_specified_recursive_protect;
bool _subst_decl_recursive_protect;
};
inline std::ostream &
operator << (std::ostream &out, const CPPScope &scope) {
scope.output(out, nullptr);
return out;
}
#endif

View File

@ -1,288 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppSimpleType.cxx
* @author drose
* @date 1999-10-19
*/
#include "cppSimpleType.h"
#include "cppGlobals.h"
/**
*
*/
CPPSimpleType::
CPPSimpleType(CPPSimpleType::Type type, int flags) :
CPPType(CPPFile()),
_type(type), _flags(flags)
{
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPSimpleType::
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 && _type != T_va_list);
}
/**
* 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 && _type != T_va_list);
}
/**
* Returns true if the type is considered a Plain Old Data (POD) type.
*/
bool CPPSimpleType::
is_trivial() const {
return (_type != T_unknown && _type != T_parameter && _type != T_auto && _type != T_va_list);
}
/**
* Returns true if the type can be safely copied by memcpy or memmove.
*/
bool CPPSimpleType::
is_trivially_copyable() const {
return (_type != T_unknown && _type != T_parameter && _type != T_auto && _type != T_va_list);
}
/**
* 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 == nullptr) {
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.
*/
bool CPPSimpleType::
is_default_constructible() const {
return (_type != T_void);
}
/**
* Returns true if the type is copy-constructible.
*/
bool CPPSimpleType::
is_copy_constructible() const {
return (_type != T_void);
}
/**
* Returns true if the type is copy-assignable.
*/
bool CPPSimpleType::
is_copy_assignable() 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.
*
* This sort of type is created to handle instance declarations that initially
* look like function prototypes.
*/
bool CPPSimpleType::
is_parameter_expr() const {
return (_type == T_parameter);
}
/**
*
*/
std::string CPPSimpleType::
get_preferred_name() const {
// Simple types always prefer to use their native types.
return get_local_name();
}
/**
*
*/
void CPPSimpleType::
output(std::ostream &out, int, CPPScope *, bool) const {
if (_flags & F_unsigned) {
out << "unsigned ";
}
if (_flags & F_signed) {
out << "signed ";
}
if ((_type == T_int && (_flags & F_longlong) != 0) &&
!cpp_longlong_keyword.empty()) {
// It's a long long, and we have a specific long long type name. This is
// to output code for compilers that don't recognize "long long int".
out << cpp_longlong_keyword;
return;
}
if (_flags & F_longlong) {
out << "long long ";
} else if (_flags & F_long) {
out << "long ";
} else if (_flags & F_short) {
out << "short ";
}
switch (_type) {
case T_unknown:
out << "unknown";
break;
case T_bool:
out << "bool";
break;
case T_char:
out << "char";
break;
case T_wchar_t:
out << "wchar_t";
break;
case T_char8_t:
out << "char8_t";
break;
case T_char16_t:
out << "char16_t";
break;
case T_char32_t:
out << "char32_t";
break;
case T_int:
out << "int";
break;
case T_float:
out << "float";
break;
case T_double:
out << "double";
break;
case T_void:
out << "void";
break;
case T_nullptr:
out << "decltype(nullptr)";
break;
case T_parameter:
out << "parameter";
break;
case T_auto:
out << "auto";
break;
case T_va_list:
out << "__builtin_va_list";
break;
default:
out << "***invalid type***";
}
}
/**
*
*/
CPPDeclaration::SubType CPPSimpleType::
get_subtype() const {
return ST_simple;
}
/**
*
*/
CPPSimpleType *CPPSimpleType::
as_simple_type() {
return this;
}
/**
* Called by CPPDeclaration() to determine whether this type is equivalent to
* another type of the same type.
*/
bool CPPSimpleType::
is_equal(const CPPDeclaration *other) const {
const CPPSimpleType *ot = ((CPPDeclaration *)other)->as_simple_type();
assert(ot != nullptr);
return _type == ot->_type && _flags == ot->_flags;
}
/**
* Called by CPPDeclaration() to determine whether this type should be ordered
* before another type of the same type, in an arbitrary but fixed ordering.
*/
bool CPPSimpleType::
is_less(const CPPDeclaration *other) const {
const CPPSimpleType *ot = ((CPPDeclaration *)other)->as_simple_type();
assert(ot != nullptr);
if (_type != ot->_type) {
return _type < ot->_type;
}
return _flags < ot->_flags;
}

View File

@ -1,100 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppSimpleType.h
* @author drose
* @date 1999-10-19
*/
#ifndef CPPSIMPLETYPE_H
#define CPPSIMPLETYPE_H
#include "dtoolbase.h"
#include "cppType.h"
/**
* Represents a C++ fundamental type.
*/
class CPPSimpleType : public CPPType {
public:
enum Type {
T_unknown,
T_bool,
T_char,
T_wchar_t,
T_char8_t,
T_char16_t,
T_char32_t,
T_int,
T_float,
T_double,
T_void,
// We need something to represent the type of nullptr so that we can
// return it from decltype(nullptr). Note that this is not the same as
// 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,
// T_auto is also a special type that corresponds to the "auto" keyword
// used in a variable assignment. The type of it is automatically
// determined at a later stage based on the type of the expression that is
// assigned to it.
T_auto,
// This is also a special built-in type.
T_va_list,
};
enum Flags {
F_long = 0x001,
F_longlong = 0x002,
F_short = 0x004,
F_unsigned = 0x008,
F_signed = 0x010,
};
CPPSimpleType(Type type, int flags = 0);
Type _type;
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_trivially_copyable() const;
virtual bool is_constructible(const CPPType *type) const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_copy_assignable() const;
virtual bool is_destructible() const;
virtual bool is_parameter_expr() const;
virtual std::string get_preferred_name() const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPSimpleType *as_simple_type();
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,132 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppStructType.h
* @author drose
* @date 1999-10-19
*/
#ifndef CPPSTRUCTTYPE_H
#define CPPSTRUCTTYPE_H
#include "dtoolbase.h"
#include "cppIdentifier.h"
#include "cppExtensionType.h"
#include "cppFunctionGroup.h"
#include "cppVisibility.h"
#include <vector>
#include <list>
class CPPScope;
class CPPTypeProxy;
/**
*
*/
class CPPStructType : public CPPExtensionType {
public:
CPPStructType(Type type, CPPIdentifier *ident,
CPPScope *current_scope,
CPPScope *scope,
const CPPFile &file,
CPPAttributeList attr = CPPAttributeList());
CPPStructType(const CPPStructType &copy);
void operator = (const CPPStructType &copy);
void append_derivation(CPPType *base, CPPVisibility vis, bool is_virtual);
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_trivially_copyable() 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_copy_assignable() 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 = V_public) const;
bool is_copy_assignable(CPPVisibility min_vis) const;
bool is_move_assignable(CPPVisibility min_vis = V_public) 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;
CPPInstance *get_copy_constructor() const;
CPPInstance *get_move_constructor() const;
CPPFunctionGroup *get_assignment_operator() const;
CPPInstance *get_copy_assignment_operator() const;
CPPInstance *get_move_assignment_operator() const;
CPPInstance *get_destructor() const;
virtual CPPDeclaration *
instantiate(const CPPTemplateParameterList *actual_params,
CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPStructType *as_struct_type();
CPPScope *_scope;
bool _incomplete;
bool _final;
class Base {
public:
void output(std::ostream &out) const;
CPPType *_base;
CPPVisibility _vis;
bool _is_virtual;
};
typedef std::vector<Base> Derivation;
Derivation _derivation;
typedef std::list<CPPInstance *> VFunctions;
void get_virtual_funcs(VFunctions &funcs) const;
void get_pure_virtual_funcs(VFunctions &funcs) const;
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
bool _subst_decl_recursive_protect;
typedef std::vector<CPPTypeProxy *> Proxies;
Proxies _proxies;
};
inline std::ostream &operator << (std::ostream &out, const CPPStructType::Base &base) {
base.output(out);
return out;
}
#endif

View File

@ -1,175 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTBDType.cxx
* @author drose
* @date 1999-11-05
*/
#include "cppTBDType.h"
#include "cppIdentifier.h"
#include "cppSimpleType.h"
/**
*
*/
CPPTBDType::
CPPTBDType(CPPIdentifier *ident) :
CPPType(CPPFile()),
_ident(ident)
{
_subst_decl_recursive_protect = false;
}
/**
* If this CPPType object is a forward reference or other nonspecified
* reference to a type that might now be known a real type, returns the real
* type. Otherwise returns the type itself.
*/
CPPType *CPPTBDType::
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
CPPType *type = _ident->find_type(current_scope, global_scope);
if (type != nullptr) {
return type;
}
return this;
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPTBDType::
is_tbd() const {
return true;
}
/**
* Returns a fundametal one-word name for the type. This name will not
* include any scoping operators or template parameters, so it may not be a
* compilable reference to the type.
*/
std::string CPPTBDType::
get_simple_name() const {
return _ident->get_simple_name();
}
/**
* Returns the compilable, correct name for this type within the indicated
* scope. If the scope is NULL, within the scope the type is declared in.
*/
std::string CPPTBDType::
get_local_name(CPPScope *scope) const {
return _ident->get_local_name(scope);
}
/**
* Returns the compilable, correct name for the type, with completely explicit
* scoping.
*/
std::string CPPTBDType::
get_fully_scoped_name() const {
return _ident->get_fully_scoped_name();
}
/**
*
*/
CPPDeclaration *CPPTBDType::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
CPPDeclaration *top =
CPPDeclaration::substitute_decl(subst, current_scope, global_scope);
if (top != this) {
return top;
}
// Protect against recursive entry into this function block. I know it's
// ugly--have you got any better suggestions?
if (_subst_decl_recursive_protect) {
// We're already executing this block.
return this;
}
_subst_decl_recursive_protect = true;
CPPTBDType *rep = new CPPTBDType(*this);
rep->_ident = _ident->substitute_decl(subst, current_scope, global_scope);
if (rep->_ident == _ident) {
delete rep;
rep = this;
}
rep = CPPType::new_type(rep)->as_tbd_type();
assert(rep != nullptr);
CPPType *result = rep;
// Can we now define it as a real type?
CPPType *type = rep->_ident->find_type(current_scope, global_scope, subst);
if (type != nullptr) {
result = type;
}
subst.insert(SubstDecl::value_type(this, result));
_subst_decl_recursive_protect = false;
return result;
}
/**
*
*/
void CPPTBDType::
output(std::ostream &out, int, CPPScope *, bool) const {
out /* << "typename " */ << *_ident;
}
/**
*
*/
CPPDeclaration::SubType CPPTBDType::
get_subtype() const {
return ST_tbd;
}
/**
*
*/
CPPTBDType *CPPTBDType::
as_tbd_type() {
return this;
}
/**
* Called by CPPDeclaration() to determine whether this type is equivalent to
* another type of the same type.
*/
bool CPPTBDType::
is_equal(const CPPDeclaration *other) const {
const CPPTBDType *ot = ((CPPDeclaration *)other)->as_tbd_type();
assert(ot != nullptr);
return (*_ident) == (*ot->_ident);
}
/**
* Called by CPPDeclaration() to determine whether this type should be ordered
* before another type of the same type, in an arbitrary but fixed ordering.
*/
bool CPPTBDType::
is_less(const CPPDeclaration *other) const {
const CPPTBDType *ot = ((CPPDeclaration *)other)->as_tbd_type();
assert(ot != nullptr);
return (*_ident) < (*ot->_ident);
}

View File

@ -1,62 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTBDType.h
* @author drose
* @date 1999-11-05
*/
#ifndef CPPTBDTYPE_H
#define CPPTBDTYPE_H
#include "dtoolbase.h"
#include "cppType.h"
class CPPIdentifier;
/**
* This represents a type whose exact meaning is still to-be-determined. It
* happens when a typename is referenced in a template class (especially using
* the 'typename' keyword) but the actual type cannot be known until the class
* is instantiated.
*/
class CPPTBDType : public CPPType {
public:
CPPTBDType(CPPIdentifier *ident);
virtual CPPType *resolve_type(CPPScope *current_scope,
CPPScope *global_scope);
virtual bool is_tbd() const;
virtual std::string get_simple_name() const;
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
virtual std::string get_fully_scoped_name() const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPTBDType *as_tbd_type();
CPPIdentifier *_ident;
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
private:
bool _subst_decl_recursive_protect;
};
#endif

View File

@ -1,234 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTemplateParameterList.cxx
* @author drose
* @date 1999-10-28
*/
#include "cppTemplateParameterList.h"
#include "cppClassTemplateParameter.h"
#include "cppInstance.h"
#include "cppExpression.h"
/**
*
*/
CPPTemplateParameterList::
CPPTemplateParameterList() {
}
/**
*
*/
std::string CPPTemplateParameterList::
get_string() const {
std::ostringstream strname;
strname << "< " << *this << " >";
return strname.str();
}
/**
* Matches up the actual parameters one-to-one with the formal parameters they
* are replacing, so the template may be instantiated by swapping out each
* occurrence of a template standin type with its appropriate replacement.
*/
void CPPTemplateParameterList::
build_subst_decl(const CPPTemplateParameterList &formal_params,
CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) const {
Parameters::const_iterator pfi, pai;
for (pfi = formal_params._parameters.begin(), pai = _parameters.begin();
pfi != formal_params._parameters.end() && pai != _parameters.end();
++pfi, ++pai) {
CPPDeclaration *formal = *pfi;
CPPDeclaration *actual = *pai;
if (actual->as_type()) {
actual = actual->as_type()->resolve_type(current_scope, global_scope);
}
if (!(formal == actual)) {
subst.insert(CPPDeclaration::SubstDecl::value_type(formal, actual));
}
}
// Fill in the default template parameters.
while (pfi != formal_params._parameters.end()) {
CPPDeclaration *decl = (*pfi);
if (decl->as_instance()) {
// A value template parameter. Its default is an expression.
CPPInstance *inst = decl->as_instance();
if (inst->_initializer != nullptr) {
CPPDeclaration *decl =
inst->_initializer->substitute_decl(subst, current_scope,
global_scope);
if (!(*decl == *inst)) {
subst.insert(CPPDeclaration::SubstDecl::value_type
(inst, decl));
}
}
} else if (decl->as_class_template_parameter()) {
// A class template parameter.
CPPClassTemplateParameter *cparam = decl->as_class_template_parameter();
if (cparam->_default_type != nullptr) {
CPPDeclaration *decl =
cparam->_default_type->substitute_decl(subst, current_scope,
global_scope);
if (!(*cparam == *decl)) {
subst.insert(CPPDeclaration::SubstDecl::value_type
(cparam, decl));
}
}
}
++pfi;
}
}
/**
* This function returns true if all the parameters in the list are real
* expressions or classes, and not types yet to-be-determined or template
* parameter types. That is, this returns true for a normal template
* instantiation, and false for a template instantiation based on template
* parameters that have not yet been specified.
*/
bool CPPTemplateParameterList::
is_fully_specified() const {
for (int i = 0; i < (int)_parameters.size(); ++i) {
if (!_parameters[i]->is_fully_specified()) {
return false;
}
}
return true;
}
/**
* Returns true if any type within the parameter list is a CPPTBDType and thus
* isn't fully determined right now.
*/
bool CPPTemplateParameterList::
is_tbd() const {
for (int i = 0; i < (int)_parameters.size(); ++i) {
CPPType *type = _parameters[i]->as_type();
if (type != nullptr &&
(type->is_tbd() || type->as_class_template_parameter() != nullptr)) {
return true;
}
CPPExpression *expr = _parameters[i]->as_expression();
if (expr != nullptr && expr->is_tbd()) {
return true;
}
}
return false;
}
/**
*
*/
bool CPPTemplateParameterList::
operator == (const CPPTemplateParameterList &other) const {
if (_parameters.size() != other._parameters.size()) {
return false;
}
for (int i = 0; i < (int)_parameters.size(); ++i) {
if (*_parameters[i] != *other._parameters[i]) {
return false;
}
}
return true;
}
/**
*
*/
bool CPPTemplateParameterList::
operator != (const CPPTemplateParameterList &other) const {
return !(*this == other);
}
/**
*
*/
bool CPPTemplateParameterList::
operator < (const CPPTemplateParameterList &other) const {
if (_parameters.size() != other._parameters.size()) {
return _parameters.size() < other._parameters.size();
}
for (int i = 0; i < (int)_parameters.size(); ++i) {
if (*_parameters[i] != *other._parameters[i]) {
return *_parameters[i] < *other._parameters[i];
}
}
return false;
}
/**
*
*/
CPPTemplateParameterList *CPPTemplateParameterList::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
CPPTemplateParameterList *rep = new CPPTemplateParameterList(*this);
bool anything_changed = false;
for (int i = 0; i < (int)rep->_parameters.size(); ++i) {
rep->_parameters[i] =
_parameters[i]->substitute_decl(subst, current_scope, global_scope);
if (rep->_parameters[i] != _parameters[i]) {
anything_changed = true;
}
}
if (!anything_changed) {
delete rep;
rep = this;
}
return rep;
}
/**
*
*/
void CPPTemplateParameterList::
output(std::ostream &out, CPPScope *scope) const {
if (!_parameters.empty()) {
Parameters::const_iterator pi = _parameters.begin();
(*pi)->output(out, 0, scope, false);
++pi;
while (pi != _parameters.end()) {
out << ", ";
(*pi)->output(out, 0, scope, false);
++pi;
}
}
}
/**
* Writes the list as a set of formal parameters for a template scope.
* Includes the keyword "template" and the angle brackets, as well as the
* trailing newline.
*/
void CPPTemplateParameterList::
write_formal(std::ostream &out, CPPScope *scope) const {
out << "template<";
if (!_parameters.empty()) {
Parameters::const_iterator pi = _parameters.begin();
(*pi)->output(out, 0, scope, true);
++pi;
while (pi != _parameters.end()) {
out << ", ";
(*pi)->output(out, 0, scope, true);
++pi;
}
}
out << ">\n";
}

View File

@ -1,76 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTemplateParameterList.h
* @author drose
* @date 1999-10-28
*/
#ifndef CPPTEMPLATEPARAMETERLIST_H
#define CPPTEMPLATEPARAMETERLIST_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
#include <vector>
#include <string>
class CPPScope;
/**
* This class serves to store the parameter list for a template function or
* class, both for the formal parameter list (given when the template is
* defined) and for the actual parameter list (given when the template is
* instantiated).
*/
class CPPTemplateParameterList {
public:
CPPTemplateParameterList();
std::string get_string() const;
void build_subst_decl(const CPPTemplateParameterList &formal_params,
CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) const;
bool is_fully_specified() const;
bool is_tbd() const;
bool operator == (const CPPTemplateParameterList &other) const;
bool operator != (const CPPTemplateParameterList &other) const;
bool operator < (const CPPTemplateParameterList &other) const;
CPPTemplateParameterList *substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
void output(std::ostream &out, CPPScope *scope) const;
void write_formal(std::ostream &out, CPPScope *scope) const;
typedef std::vector<CPPDeclaration *> Parameters;
Parameters _parameters;
};
inline std::ostream &
operator << (std::ostream &out, const CPPTemplateParameterList &plist) {
plist.output(out, nullptr);
return out;
}
// This is an STL function object used to uniquely order
// CPPTemplateParameterList pointers.
class CPPTPLCompare {
public:
bool operator () (const CPPTemplateParameterList *a,
const CPPTemplateParameterList *b) const {
return (*a) < (*b);
}
};
#endif

View File

@ -1,172 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTemplateScope.cxx
* @author drose
* @date 1999-10-28
*/
#include "cppTemplateScope.h"
#include "cppExtensionType.h"
#include "cppClassTemplateParameter.h"
#include "cppIdentifier.h"
#include "cppTypedefType.h"
using std::string;
/**
*
*/
CPPTemplateScope::
CPPTemplateScope(CPPScope *parent_scope) :
CPPScope(parent_scope, CPPNameComponent("template"), V_public)
{
}
/**
*
*/
void CPPTemplateScope::
add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
CPPPreprocessor *preprocessor,
const cppyyltype &pos) {
decl->_template_scope = this;
assert(_parent_scope != nullptr);
_parent_scope->add_declaration(decl, global_scope, preprocessor, pos);
}
/**
*
*/
void CPPTemplateScope::
add_enum_value(CPPInstance *inst) {
inst->_template_scope = this;
assert(_parent_scope != nullptr);
_parent_scope->add_enum_value(inst);
}
/**
*
*/
void CPPTemplateScope::
define_typedef_type(CPPTypedefType *type, CPPPreprocessor *error_sink) {
type->_template_scope = this;
assert(_parent_scope != nullptr);
_parent_scope->define_typedef_type(type, error_sink);
}
/**
*
*/
void CPPTemplateScope::
define_extension_type(CPPExtensionType *type, CPPPreprocessor *error_sink) {
type->_template_scope = this;
assert(_parent_scope != nullptr);
_parent_scope->define_extension_type(type, error_sink);
}
/**
*
*/
void CPPTemplateScope::
define_namespace(CPPNamespace *scope) {
assert(_parent_scope != nullptr);
_parent_scope->define_namespace(scope);
}
/**
*
*/
void CPPTemplateScope::
add_using(CPPUsing *using_decl, CPPScope *global_scope,
CPPPreprocessor *error_sink) {
assert(_parent_scope != nullptr);
_parent_scope->add_using(using_decl, global_scope, error_sink);
}
/**
*
*/
void CPPTemplateScope::
add_template_parameter(CPPDeclaration *param) {
_parameters._parameters.push_back(param);
CPPClassTemplateParameter *cl = param->as_class_template_parameter();
if (cl != nullptr) {
// Create an implicit typedef for this class parameter.
if (cl->_ident != nullptr) {
string name = cl->_ident->get_local_name();
_types[name] = cl;
}
}
CPPInstance *inst = param->as_instance();
if (inst != nullptr) {
// Register the variable for this value parameter.
string name = inst->get_local_name();
if (!name.empty()) {
_variables[name] = inst;
}
}
}
/**
* Returns true if this declaration is an actual, factual declaration, or
* false if some part of the declaration depends on a template parameter which
* has not yet been instantiated.
*/
bool CPPTemplateScope::
is_fully_specified() const {
return false;
}
/**
*
*/
string CPPTemplateScope::
get_simple_name() const {
assert(_parent_scope != nullptr);
return _parent_scope->get_simple_name();
}
/**
*
*/
string CPPTemplateScope::
get_local_name(CPPScope *scope) const {
assert(_parent_scope != nullptr);
return _parent_scope->get_local_name(scope);
}
/**
*
*/
string CPPTemplateScope::
get_fully_scoped_name() const {
assert(_parent_scope != nullptr);
return _parent_scope->get_fully_scoped_name();
}
/**
*
*/
void CPPTemplateScope::
output(std::ostream &out, CPPScope *scope) const {
CPPScope::output(out, scope);
out << "< ";
_parameters.output(out, scope);
out << " >";
}
/**
*
*/
CPPTemplateScope *CPPTemplateScope::
as_template_scope() {
return this;
}

View File

@ -1,58 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTemplateScope.h
* @author drose
* @date 1999-10-28
*/
#ifndef CPPTEMPLATESCOPE_H
#define CPPTEMPLATESCOPE_H
#include "dtoolbase.h"
#include "cppScope.h"
#include "cppTemplateParameterList.h"
/**
* This is an implicit scope that is created following the appearance of a
* "template<class x, class y>" or some such line in a C++ file. It simply
* defines the template parameters.
*/
class CPPTemplateScope : public CPPScope {
public:
CPPTemplateScope(CPPScope *parent_scope);
void add_template_parameter(CPPDeclaration *param);
virtual void add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
CPPPreprocessor *preprocessor,
const cppyyltype &pos);
virtual void add_enum_value(CPPInstance *inst);
virtual void define_typedef_type(CPPTypedefType *type,
CPPPreprocessor *error_sink = nullptr);
virtual void define_extension_type(CPPExtensionType *type,
CPPPreprocessor *error_sink = nullptr);
virtual void define_namespace(CPPNamespace *scope);
virtual void add_using(CPPUsing *using_decl, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr);
virtual bool is_fully_specified() const;
virtual std::string get_simple_name() const;
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
virtual std::string get_fully_scoped_name() const;
virtual void output(std::ostream &out, CPPScope *scope) const;
virtual CPPTemplateScope *as_template_scope();
CPPTemplateParameterList _parameters;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppToken.h
* @author drose
* @date 1999-10-22
*/
#ifndef CPPTOKEN_H
#define CPPTOKEN_H
#include "dtoolbase.h"
#include "cppBisonDefs.h"
/**
*
*/
class CPPToken {
public:
CPPToken(int token, int line_number = 0, int col_number = 0,
const CPPFile &file = CPPFile(""),
const std::string &str = std::string(),
const YYSTYPE &lval = YYSTYPE());
CPPToken(int token, const YYLTYPE &loc,
const std::string &str = std::string(),
const YYSTYPE &lval = YYSTYPE());
static CPPToken eof();
bool is_eof() const;
void output(std::ostream &out) const;
void output_code(std::ostream &out) const;
int _token;
YYSTYPE _lval;
YYLTYPE _lloc;
};
inline std::ostream &operator << (std::ostream &out, const CPPToken &token) {
token.output(out);
return out;
}
#endif

View File

@ -1,535 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppType.cxx
* @author drose
* @date 1999-10-19
*/
#include "cppType.h"
#include "cppConstType.h"
#include "cppPointerType.h"
#include "cppReferenceType.h"
#include "cppStructType.h"
#include "cppTypedefType.h"
#include "cppExtensionType.h"
#include <algorithm>
using std::string;
CPPType::Types CPPType::_types;
CPPType::PreferredNames CPPType::_preferred_names;
CPPType::AltNames CPPType::_alt_names;
bool CPPTypeCompare::
operator () (CPPType *a, CPPType *b) const {
return (*a) < (*b);
}
/**
*
*/
CPPType::
CPPType(const CPPFile &file) :
CPPDeclaration(file)
{
_declaration = nullptr;
// This is set true by interrogate when the "forcetype" keyword is used.
_forcetype = false;
}
/**
* If this CPPType object is a forward reference or other nonspecified
* reference to a type that might now be known a real type, returns the real
* type. Otherwise returns the type itself.
*/
CPPType *CPPType::
resolve_type(CPPScope *, CPPScope *) {
return this;
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPType::
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.
*/
bool CPPType::
is_trivial() const {
return false;
}
/**
* Returns true if the type can be safely copied by memcpy or memmove.
*/
bool CPPType::
is_trivially_copyable() 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.
*/
bool CPPType::
is_default_constructible() const {
return false;
}
/**
* Returns true if the type is copy-constructible.
*/
bool CPPType::
is_copy_constructible() const {
return false;
}
/**
* Returns true if the type is copy-assignable.
*/
bool CPPType::
is_copy_assignable() 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.
*
* This sort of type is created to handle instance declarations that initially
* look like function prototypes.
*/
bool CPPType::
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 != nullptr) {
return td_type->_type->is_enum();
}
const CPPExtensionType *ext_type = as_extension_type();
if (ext_type != nullptr) {
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 != nullptr) {
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 != nullptr) {
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 != nullptr) {
return td_type->_type->is_pointer();
}
const CPPConstType *const_type = as_const_type();
if (const_type != nullptr) {
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 != nullptr) {
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 != nullptr) {
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 != nullptr) {
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 != nullptr) {
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
* typedef'ed on declaration.
*/
bool CPPType::
has_typedef_name() const {
return !_typedefs.empty();
}
/**
* Returns a string that can be used to name the type, if has_typedef_name()
* returned true. This will be the first typedef name applied to the type.
*/
string CPPType::
get_typedef_name(CPPScope *scope) const {
if (_typedefs.empty()) {
return string();
} else {
return _typedefs.front()->get_local_name(scope);
}
}
/**
* Returns a fundametal one-word name for the type. This name will not
* include any scoping operators or template parameters, so it may not be a
* compilable reference to the type.
*/
string CPPType::
get_simple_name() const {
return get_local_name();
}
/**
* Returns the compilable, correct name for this type within the indicated
* scope. If the scope is NULL, within the scope the type is declared in.
*/
string CPPType::
get_local_name(CPPScope *scope) const {
std::ostringstream ostrm;
output(ostrm, 0, scope, false);
return ostrm.str();
}
/**
* Returns the compilable, correct name for the type, with completely explicit
* scoping.
*/
string CPPType::
get_fully_scoped_name() const {
return get_local_name();
}
/**
* Returns the best name to use for the type from a programmer's point of
* view. This will typically be a typedef name if one is available, or the
* full C++ name if it is not. The typedef may or may not be visible within
* the current scope, so this type name may not be compilable.
*/
string CPPType::
get_preferred_name() const {
string preferred_name = get_preferred_name_for(this);
if (!preferred_name.empty()) {
return preferred_name;
}
return get_local_name();
}
/**
* Returns the number of "alternate" names for this type. The alternate names
* are alternate typedef names. This list might be empty, or it might be
* long. One of these names may or may not be the same as the "preferred"
* name.
*/
int CPPType::
get_num_alt_names() const {
// We do a lookup based on the type's name, instead of its pointer, so we
// can resolve different expansions of the same type.
string tname = this->get_fully_scoped_name();
if (!tname.empty()) {
AltNames::const_iterator ai;
ai = _alt_names.find(tname);
if (ai != _alt_names.end()) {
const Names &names = (*ai).second;
return names.size();
}
}
return 0;
}
/**
* Returns the nth "alternate" name for this type. See get_num_alt_names().
*/
string CPPType::
get_alt_name(int n) const {
// We do a lookup based on the type's name, instead of its pointer, so we
// can resolve different expansions of the same type.
string tname = this->get_fully_scoped_name();
if (!tname.empty()) {
AltNames::const_iterator ai;
ai = _alt_names.find(tname);
if (ai != _alt_names.end()) {
const Names &names = (*ai).second;
if (n >= 0 && n < (int)names.size()) {
return names[n];
}
}
}
return string();
}
/**
* Returns true if the type has not yet been fully specified, false if it has.
*/
bool CPPType::
is_incomplete() 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
* different pointers or somewhat different definitions. It's useful for
* parameter matching, etc.
*/
bool CPPType::
is_equivalent(const CPPType &other) const {
if (get_subtype() != other.get_subtype()) {
return false;
}
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
* the indicated name. In most cases this will be "type name", but some types
* have special exceptions.
*/
void CPPType::
output_instance(std::ostream &out, const string &name, CPPScope *scope) const {
output_instance(out, 0, scope, false, "", name);
}
/**
* Formats a C++-looking line that defines an instance of the given type, with
* the indicated name. In most cases this will be "type name", but some types
* have special exceptions.
*/
void CPPType::
output_instance(std::ostream &out, int indent_level, CPPScope *scope,
bool complete, const string &prename,
const string &name) const {
output(out, indent_level, scope, complete);
out << " " << prename << name;
}
/**
*
*/
CPPType *CPPType::
as_type() {
return this;
}
/**
* This should be called whenever a new CPPType object is created. It will
* uniquify the type pointers by checking to see if some equivalent CPPType
* object has previously been created; if it has, it returns the old object
* and deletes the new one. Otherwise, it stores the new one and returns it.
*/
CPPType *CPPType::
new_type(CPPType *type) {
std::pair<Types::iterator, bool> result = _types.insert(type);
if (result.second) {
// The insertion has taken place; thus, this is the first time this type
// has been declared.
assert(*result.first == type);
return type;
}
// If this triggers, we probably messed up by defining is_less()
// incorrectly; they provide a relative ordering even though they are equal
// to each other. Or, we provided an is_equal() that gives false negatives.
assert(**result.first == *type);
// The insertion has not taken place; thus, there was previously another
// equivalent type declared.
if (*result.first != type) {
// *** Something wrong here. Deleting this should always be safe;
// however, it's not. Thus, someone failed to call new_type() on a type
// pointer before saving it somewhere. Fix me soon. ****
delete type;
}
return *result.first;
}
/**
* Records a global typedef name associated with the indicated Type. This
* will be an "alt" name, and it may also become the "preferred" name.
*/
void CPPType::
record_alt_name_for(const CPPType *type, const string &name) {
if (!name.empty()) {
string tname = type->get_fully_scoped_name();
if (!tname.empty()) {
if (tname.find('<') != string::npos) {
// If the name contains a funny character like a template name, then
// we implicitly take the first typedef as the preferred name.
_preferred_names.insert(PreferredNames::value_type(tname, name));
}
Names &names = _alt_names[tname];
if (find(names.begin(), names.end(), name) == names.end()) {
// It's not already recorded as an alt name, so record it now.
names.push_back(name);
}
}
}
}
/**
* Returns the previously-stored "preferred" name associated with the type, if
* any, or empty string if no name is associated.
*/
string CPPType::
get_preferred_name_for(const CPPType *type) {
// We do a lookup based on the type's name, instead of its pointer, so we
// can resolve different expansions of the same type.
string tname = type->get_fully_scoped_name();
if (!tname.empty()) {
PreferredNames::const_iterator pi;
pi = _preferred_names.find(tname);
if (pi != _preferred_names.end()) {
return (*pi).second;
}
}
return string();
}

View File

@ -1,115 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppType.h
* @author drose
* @date 1999-10-19
*/
#ifndef CPPTYPE_H
#define CPPTYPE_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
#include <set>
class CPPType;
class CPPTypedefType;
class CPPTypeDeclaration;
// This is an STL function object used to uniquely order CPPType pointers.
class CPPTypeCompare {
public:
bool operator () (CPPType *a, CPPType *b) const;
};
/**
*
*/
class CPPType : public CPPDeclaration {
public:
typedef std::vector<CPPTypedefType *> Typedefs;
Typedefs _typedefs;
CPPType(const CPPFile &file);
virtual CPPType *resolve_type(CPPScope *current_scope,
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_trivially_copyable() const;
virtual bool is_constructible(const CPPType *type) const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_copy_assignable() 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;
std::string get_typedef_name(CPPScope *scope = nullptr) const;
virtual std::string get_simple_name() const;
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
virtual std::string get_fully_scoped_name() const;
virtual std::string get_preferred_name() const;
int get_num_alt_names() const;
std::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(std::ostream &out, const std::string &name,
CPPScope *scope) const;
virtual void output_instance(std::ostream &out, int indent_level,
CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const;
virtual CPPType *as_type();
static CPPType *new_type(CPPType *type);
static void record_alt_name_for(const CPPType *type, const std::string &name);
static std::string get_preferred_name_for(const CPPType *type);
CPPTypeDeclaration *_declaration;
bool _forcetype;
protected:
typedef std::set<CPPType *, CPPTypeCompare> Types;
static Types _types;
typedef std::map<std::string, std::string> PreferredNames;
static PreferredNames _preferred_names;
typedef std::vector<std::string> Names;
typedef std::map<std::string, Names> AltNames;
static AltNames _alt_names;
};
#endif

View File

@ -1,67 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTypeDeclaration.cxx
* @author drose
* @date 2000-08-14
*/
#include "cppTypeDeclaration.h"
/**
* Constructs a new CPPTypeDeclaration object for the given type.
*/
CPPTypeDeclaration::
CPPTypeDeclaration(CPPType *type) :
CPPInstance(type, nullptr)
{
assert(_type != nullptr);
if (_type->_declaration == nullptr) {
_type->_declaration = this;
}
}
/**
*
*/
CPPDeclaration *CPPTypeDeclaration::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
CPPDeclaration *decl =
CPPInstance::substitute_decl(subst, current_scope, global_scope);
assert(decl != nullptr);
if (decl->as_type_declaration()) {
return decl;
}
assert(decl->as_instance() != nullptr);
return new CPPTypeDeclaration(decl->as_instance()->_type);
}
/**
*
*/
void CPPTypeDeclaration::
output(std::ostream &out, int indent_level, CPPScope *scope, bool) const {
_type->output(out, indent_level, scope, true);
}
/**
*
*/
CPPDeclaration::SubType CPPTypeDeclaration::
get_subtype() const {
return ST_type_declaration;
}
/**
*
*/
CPPTypeDeclaration *CPPTypeDeclaration::
as_type_declaration() {
return this;
}

View File

@ -1,41 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTypeDeclaration.h
* @author drose
* @date 2000-08-14
*/
#ifndef CPPTYPEDECLARATION_H
#define CPPTYPEDECLARATION_H
#include "dtoolbase.h"
#include "cppInstance.h"
/**
* A CPPTypeDeclaration is a special declaration that represents the top-level
* declaration of a type in a source file. Typically this is the first
* appearance of the type.
*/
class CPPTypeDeclaration : public CPPInstance {
public:
CPPTypeDeclaration(CPPType *type);
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPTypeDeclaration *as_type_declaration();
};
#endif

View File

@ -1,77 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTypeParser.cxx
* @author drose
* @date 1999-12-14
*/
#include "cppTypeParser.h"
#include "cppType.h"
/**
*
*/
CPPTypeParser::
CPPTypeParser(CPPScope *current_scope, CPPScope *global_scope) :
_current_scope(current_scope),
_global_scope(global_scope)
{
_type = nullptr;
}
/**
*
*/
CPPTypeParser::
~CPPTypeParser() {
}
/**
*
*/
bool CPPTypeParser::
parse_type(const std::string &type) {
if (!init_type(type)) {
std::cerr << "Unable to parse type\n";
return false;
}
_type = ::parse_type(this, _current_scope, _global_scope);
return get_error_count() == 0;
}
/**
*
*/
bool CPPTypeParser::
parse_type(const std::string &type, const CPPPreprocessor &filepos) {
if (!init_type(type)) {
std::cerr << "Unable to parse type\n";
return false;
}
copy_filepos(filepos);
_type = ::parse_type(this, _current_scope, _global_scope);
return get_error_count() == 0;
}
/**
*
*/
void CPPTypeParser::
output(std::ostream &out) const {
if (_type == nullptr) {
out << "(null type)";
} else {
out << *_type;
}
}

View File

@ -1,48 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTypeParser.h
* @author drose
* @date 1999-12-14
*/
#ifndef CPPTYPEPARSER_H
#define CPPTYPEPARSER_H
#include "dtoolbase.h"
#include "cppPreprocessor.h"
class CPPType;
class CPPScope;
/**
*
*/
class CPPTypeParser : public CPPPreprocessor {
public:
CPPTypeParser(CPPScope *current_scope, CPPScope *global_scope);
~CPPTypeParser();
bool parse_type(const std::string &type);
bool parse_type(const std::string &type, const CPPPreprocessor &filepos);
void output(std::ostream &out) const;
CPPScope *_current_scope;
CPPScope *_global_scope;
CPPType *_type;
};
inline std::ostream &
operator << (std::ostream &out, const CPPTypeParser &ep) {
ep.output(out);
return out;
}
#endif

View File

@ -1,319 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTypeProxy.cxx
* @author drose
* @date 1999-12-07
*/
#include "cppTypeProxy.h"
#include "cppFile.h"
using std::string;
/**
*
*/
CPPTypeProxy::
CPPTypeProxy() :
CPPType(CPPFile())
{
_actual_type = nullptr;
}
/**
* If this CPPType object is a forward reference or other nonspecified
* reference to a type that might now be known a real type, returns the real
* type. Otherwise returns the type itself.
*/
CPPType *CPPTypeProxy::
resolve_type(CPPScope *, CPPScope *) {
if (_actual_type == nullptr) {
return this;
}
return _actual_type;
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPTypeProxy::
is_tbd() const {
if (_actual_type == nullptr) {
return false;
}
return _actual_type->is_tbd();
}
/**
* 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
* typedef'ed on declaration.
*/
bool CPPTypeProxy::
has_typedef_name() const {
if (_actual_type == nullptr) {
return false;
}
return _actual_type->has_typedef_name();
}
/**
* Returns a string that can be used to name the type, if has_typedef_name()
* returned true. This will be the first typedef name applied to the type.
*/
string CPPTypeProxy::
get_typedef_name(CPPScope *) const {
if (_actual_type == nullptr) {
return string();
}
return _actual_type->get_typedef_name();
}
/**
* Returns a fundametal one-word name for the type. This name will not
* include any scoping operators or template parameters, so it may not be a
* compilable reference to the type.
*/
string CPPTypeProxy::
get_simple_name() const {
if (_actual_type == nullptr) {
return "unknown";
}
return _actual_type->get_simple_name();
}
/**
* Returns the compilable, correct name for this type within the indicated
* scope. If the scope is NULL, within the scope the type is declared in.
*/
string CPPTypeProxy::
get_local_name(CPPScope *scope) const {
if (_actual_type == nullptr) {
return "unknown";
}
return _actual_type->get_local_name(scope);
}
/**
* Returns the compilable, correct name for the type, with completely explicit
* scoping.
*/
string CPPTypeProxy::
get_fully_scoped_name() const {
if (_actual_type == nullptr) {
return "unknown";
}
return _actual_type->get_fully_scoped_name();
}
/**
* Returns the best name to use for the type from a programmer's point of
* view. This will typically be a typedef name if one is available, or the
* full C++ name if it is not. The typedef may or may not be visible within
* the current scope, so this type name may not be compilable.
*/
string CPPTypeProxy::
get_preferred_name() const {
if (_actual_type == nullptr) {
return "unknown";
}
return _actual_type->get_preferred_name();
}
/**
* Returns true if the type has not yet been fully specified, false if it has.
*/
bool CPPTypeProxy::
is_incomplete() const {
if (_actual_type == nullptr) {
return true;
}
return _actual_type->is_incomplete();
}
/**
* Formats a C++-looking line that defines an instance of the given type, with
* the indicated name. In most cases this will be "type name", but some types
* have special exceptions.
*/
void CPPTypeProxy::
output_instance(std::ostream &out, int indent_level, CPPScope *scope,
bool complete, const string &prename,
const string &name) const {
if (_actual_type == nullptr) {
out << "unknown " << prename << name;
return;
}
_actual_type->output_instance(out, indent_level, scope, complete,
prename, name);
}
/**
*
*/
void CPPTypeProxy::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
if (_actual_type == nullptr) {
out << "unknown";
return;
}
_actual_type->output(out, indent_level, scope, complete);
}
/**
*
*/
CPPDeclaration::SubType CPPTypeProxy::
get_subtype() const {
return ST_type_proxy;
}
/**
*
*/
CPPType *CPPTypeProxy::
as_type() {
if (_actual_type == nullptr) {
return this;
}
return _actual_type;
}
/**
*
*/
CPPSimpleType *CPPTypeProxy::
as_simple_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_simple_type();
}
/**
*
*/
CPPPointerType *CPPTypeProxy::
as_pointer_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_pointer_type();
}
/**
*
*/
CPPReferenceType *CPPTypeProxy::
as_reference_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_reference_type();
}
/**
*
*/
CPPArrayType *CPPTypeProxy::
as_array_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_array_type();
}
/**
*
*/
CPPConstType *CPPTypeProxy::
as_const_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_const_type();
}
/**
*
*/
CPPFunctionType *CPPTypeProxy::
as_function_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_function_type();
}
/**
*
*/
CPPExtensionType *CPPTypeProxy::
as_extension_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_extension_type();
}
/**
*
*/
CPPStructType *CPPTypeProxy::
as_struct_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_struct_type();
}
/**
*
*/
CPPEnumType *CPPTypeProxy::
as_enum_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_enum_type();
}
/**
*
*/
CPPTBDType *CPPTypeProxy::
as_tbd_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_tbd_type();
}
/**
*
*/
CPPTypedefType *CPPTypeProxy::
as_typedef_type() {
if (_actual_type == nullptr) {
return nullptr;
}
return _actual_type->as_typedef_type();
}
/**
*
*/
CPPTypeProxy *CPPTypeProxy::
as_type_proxy() {
return this;
}

View File

@ -1,71 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTypeProxy.h
* @author drose
* @date 1999-12-07
*/
#ifndef CPPTYPEPROXY_H
#define CPPTYPEPROXY_H
#include "dtoolbase.h"
#include "cppType.h"
/**
* This is a special kind of type that is a placeholder for some type,
* currently unknown, that will be filled in later. It's used when a type
* that references itself must instantiate.
*/
class CPPTypeProxy : public CPPType {
public:
CPPTypeProxy();
virtual CPPType *resolve_type(CPPScope *current_scope,
CPPScope *global_scope);
virtual bool is_tbd() const;
bool has_typedef_name() const;
std::string get_typedef_name(CPPScope *scope = nullptr) const;
virtual std::string get_simple_name() const;
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
virtual std::string get_fully_scoped_name() const;
virtual std::string get_preferred_name() const;
virtual bool is_incomplete() const;
virtual void output_instance(std::ostream &out, int indent_level,
CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPType *as_type();
virtual CPPSimpleType *as_simple_type();
virtual CPPPointerType *as_pointer_type();
virtual CPPReferenceType *as_reference_type();
virtual CPPArrayType *as_array_type();
virtual CPPConstType *as_const_type();
virtual CPPFunctionType *as_function_type();
virtual CPPExtensionType *as_extension_type();
virtual CPPStructType *as_struct_type();
virtual CPPEnumType *as_enum_type();
virtual CPPTBDType *as_tbd_type();
virtual CPPTypedefType *as_typedef_type();
virtual CPPTypeProxy *as_type_proxy();
CPPType *_actual_type;
};
#endif

View File

@ -1,471 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTypedefType.cxx
* @author rdb
* @date 2014-08-01
*/
#include "cppTypedefType.h"
#include "cppIdentifier.h"
#include "cppInstanceIdentifier.h"
#include "cppTemplateScope.h"
#include "indent.h"
using std::string;
/**
*
*/
CPPTypedefType::
CPPTypedefType(CPPType *type, const string &name, CPPScope *current_scope) :
CPPType(CPPFile()),
_type(type),
_ident(new CPPIdentifier(name)),
_using(false)
{
if (_ident != nullptr) {
_ident->_native_scope = current_scope;
}
_subst_decl_recursive_protect = false;
// assert(_type != NULL); if (global) { _type->_typedefs.push_back(this);
// CPPType::record_alt_name_for(_type, inst->get_local_name()); }
}
/**
*
*/
CPPTypedefType::
CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope,
CPPAttributeList attr) :
CPPType(CPPFile()),
_type(type),
_ident(ident),
_using(false)
{
if (_ident != nullptr) {
_ident->_native_scope = current_scope;
}
_subst_decl_recursive_protect = false;
_attributes = std::move(attr);
}
/**
* Constructs a new CPPTypedefType object that defines a typedef to the
* indicated type according to the type and the InstanceIdentifier. The
* InstanceIdentifier pointer is deallocated.
*/
CPPTypedefType::
CPPTypedefType(CPPType *type, CPPInstanceIdentifier *ii,
CPPScope *current_scope, const CPPFile &file) :
CPPType(file),
_using(false)
{
assert(ii != nullptr);
_type = ii->unroll_type(type);
_ident = ii->_ident;
_attributes = std::move(ii->_attributes);
ii->_ident = nullptr;
delete ii;
if (_ident != nullptr) {
_ident->_native_scope = current_scope;
}
_subst_decl_recursive_protect = false;
}
/**
*
*/
bool CPPTypedefType::
is_scoped() const {
if (_ident == nullptr) {
return false;
} else {
return _ident->is_scoped();
}
}
/**
*
*/
CPPScope *CPPTypedefType::
get_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink) const {
if (_ident == nullptr) {
return current_scope;
} else {
return _ident->get_scope(current_scope, global_scope, error_sink);
}
}
/**
*
*/
string CPPTypedefType::
get_simple_name() const {
if (_ident == nullptr) {
return "";
}
return _ident->get_simple_name();
}
/**
*
*/
string CPPTypedefType::
get_local_name(CPPScope *scope) const {
if (_ident == nullptr) {
return "";
}
return _ident->get_local_name(scope);
}
/**
*
*/
string CPPTypedefType::
get_fully_scoped_name() const {
if (_ident == nullptr) {
return "";
}
return _ident->get_fully_scoped_name();
}
/**
* Returns true if the type has not yet been fully specified, false if it has.
*/
bool CPPTypedefType::
is_incomplete() const {
return false;
// return _type->is_incomplete();
}
/**
* Returns true if the type, or any nested type within the type, is a
* CPPTBDType and thus isn't fully determined right now. In this case,
* calling resolve_type() may or may not resolve the type.
*/
bool CPPTypedefType::
is_tbd() const {
if (_ident != nullptr && _ident->is_tbd()) {
return true;
}
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.
*/
bool CPPTypedefType::
is_trivial() const {
return _type->is_trivial();
}
/**
* Returns true if the type can be safely copied by memcpy or memmove.
*/
bool CPPTypedefType::
is_trivially_copyable() const {
return _type->is_trivially_copyable();
}
/**
* 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.
*/
bool CPPTypedefType::
is_default_constructible() const {
return _type->is_default_constructible();
}
/**
* Returns true if the type is copy-constructible.
*/
bool CPPTypedefType::
is_copy_constructible() const {
return _type->is_copy_constructible();
}
/**
* Returns true if the type is copy-assignable.
*/
bool CPPTypedefType::
is_copy_assignable() const {
return _type->is_copy_assignable();
}
/**
* 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
* has not yet been instantiated.
*/
bool CPPTypedefType::
is_fully_specified() const {
if (_ident != nullptr && !_ident->is_fully_specified()) {
return false;
}
return CPPDeclaration::is_fully_specified() &&
_type->is_fully_specified();
}
/**
*
*/
CPPDeclaration *CPPTypedefType::
instantiate(const CPPTemplateParameterList *actual_params,
CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink) const {
return _type->instantiate(actual_params, current_scope, global_scope, error_sink);
}
/**
*
*/
CPPDeclaration *CPPTypedefType::
substitute_decl(CPPDeclaration::SubstDecl &subst,
CPPScope *current_scope, CPPScope *global_scope) {
if (_ident != nullptr && _ident->get_scope(current_scope, global_scope) == global_scope) {
// Hack... I know that size_t etc is supposed to work fine, so preserve
// these top-level typedefs.
CPPDeclaration *top =
CPPType::substitute_decl(subst, current_scope, global_scope);
if (top != this) {
return top;
}
top = new CPPTypedefType(*this);
subst.insert(SubstDecl::value_type(this, top));
return top;
}
return _type->substitute_decl(subst, current_scope, global_scope);
// Bah, this doesn't seem to work, and I can't figure out why. Well, for
// now, let's just substitute it with the type we're pointing to. This is
// not a huge deal for now, until we find that we need to preserve these
// typedefs.
/*
CPPDeclaration *top =
CPPType::substitute_decl(subst, current_scope, global_scope);
if (top != this) {
return top;
}
if (_subst_decl_recursive_protect) {
// We're already executing this block; we'll have to return a proxy to the
// type which we'll define later.
CPPTypeProxy *proxy = new CPPTypeProxy;
_proxies.push_back(proxy);
assert(proxy != NULL);
return proxy;
}
_subst_decl_recursive_protect = true;
CPPTypedefType *rep = new CPPTypedefType(*this);
CPPDeclaration *new_type =
_type->substitute_decl(subst, current_scope, global_scope);
rep->_type = new_type->as_type();
if (rep->_type == NULL) {
rep->_type = _type;
}
if (_ident != NULL) {
rep->_ident =
_ident->substitute_decl(subst, current_scope, global_scope);
}
if (rep->_type == _type && rep->_ident == _ident) {
delete rep;
rep = this;
}
rep = CPPType::new_type(rep)->as_typedef_type();
subst.insert(SubstDecl::value_type(this, rep));
_subst_decl_recursive_protect = false;
// Now fill in all the proxies we created for our recursive references.
Proxies::iterator pi;
for (pi = _proxies.begin(); pi != _proxies.end(); ++pi) {
(*pi)->_actual_type = rep;
}
return rep; */
}
/**
* If this CPPType object is a forward reference or other nonspecified
* reference to a type that might now be known a real type, returns the real
* type. Otherwise returns the type itself.
*/
CPPType *CPPTypedefType::
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
CPPType *ptype = _type->resolve_type(current_scope, global_scope);
if (ptype != _type) {
CPPTypedefType *rep = new CPPTypedefType(*this);
rep->_type = ptype;
return CPPType::new_type(rep);
}
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
* different pointers or somewhat different definitions. It's useful for
* parameter matching, etc.
*/
bool CPPTypedefType::
is_equivalent(const CPPType &other) const {
CPPType *ot = (CPPType *)&other;
// Unwrap all the typedefs to get to where it is pointing.
while (ot->get_subtype() == ST_typedef) {
ot = ot->as_typedef_type()->_type;
}
// Compare the unwrapped type to what we are pointing to. If we are
// pointing to a typedef ourselves, then this will automatically recurse.
return _type->is_equivalent(*ot);
}
/**
*
*/
void CPPTypedefType::
output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
string name;
if (_ident != nullptr) {
name = _ident->get_local_name(scope);
}
if (complete) {
if (_using) {
// It was declared using the "using" keyword.
if (is_template()) {
get_template_scope()->_parameters.write_formal(out, scope);
indent(out, indent_level);
}
out << "using " << name;
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
out << " = ";
_type->output(out, 0, scope, false);
} else {
if (!_attributes.is_empty()) {
out << _attributes << " ";
}
out << "typedef ";
_type->output_instance(out, indent_level, scope, false, "", name);
}
} else {
out << name;
}
}
/**
*
*/
CPPDeclaration::SubType CPPTypedefType::
get_subtype() const {
return ST_typedef;
}
/**
*
*/
CPPTypedefType *CPPTypedefType::
as_typedef_type() {
return this;
}
/**
* Called by CPPDeclaration() to determine whether this type is equivalent to
* another type of the same type.
*/
bool CPPTypedefType::
is_equal(const CPPDeclaration *other) const {
const CPPTypedefType *ot = ((CPPDeclaration *)other)->as_typedef_type();
assert(ot != nullptr);
return (*_type == *ot->_type) && (*_ident == *ot->_ident) && (_using == ot->_using);
}
/**
* Called by CPPDeclaration() to determine whether this type should be ordered
* before another type of the same type, in an arbitrary but fixed ordering.
*/
bool CPPTypedefType::
is_less(const CPPDeclaration *other) const {
return CPPDeclaration::is_less(other);
// The below code causes a crash for unknown reasons.
/*
const CPPTypedefType *ot = ((CPPDeclaration *)other)->as_typedef_type();
assert(ot != NULL);
if (_type != ot->_type) {
return _type < ot->_type;
}
if (*_ident != *ot->_ident) {
return *_ident < *ot->_ident;
}
return false; */
}

View File

@ -1,92 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppTypedefType.h
* @author rdb
* @date 2014-08-01
*/
#ifndef CPPTYPEDEFTYPE_H
#define CPPTYPEDEFTYPE_H
#include "dtoolbase.h"
#include "cppType.h"
class CPPIdentifier;
class CPPInstanceIdentifier;
/**
* A type alias created by a C++ typedef or using declaration. These aren't
* officially supposed to be types in themselves, but we represent them as
* such so that we can preserve typedef names in the generated code.
*/
class CPPTypedefType : public CPPType {
public:
CPPTypedefType(CPPType *type, const std::string &name, CPPScope *current_scope);
CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope,
CPPAttributeList attr = CPPAttributeList());
CPPTypedefType(CPPType *type, CPPInstanceIdentifier *ii,
CPPScope *current_scope, const CPPFile &file);
bool is_scoped() const;
CPPScope *get_scope(CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
virtual std::string get_simple_name() const;
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
virtual std::string get_fully_scoped_name() const;
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_trivially_copyable() const;
virtual bool is_constructible(const CPPType *type) const;
virtual bool is_default_constructible() const;
virtual bool is_copy_constructible() const;
virtual bool is_copy_assignable() const;
virtual bool is_destructible() const;
virtual bool is_fully_specified() const;
virtual CPPDeclaration *
instantiate(const CPPTemplateParameterList *actual_params,
CPPScope *current_scope, CPPScope *global_scope,
CPPPreprocessor *error_sink = nullptr) const;
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
CPPScope *current_scope,
CPPScope *global_scope);
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(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPTypedefType *as_typedef_type();
CPPType *_type;
CPPIdentifier *_ident;
bool _using;
protected:
virtual bool is_equal(const CPPDeclaration *other) const;
virtual bool is_less(const CPPDeclaration *other) const;
bool _subst_decl_recursive_protect;
typedef std::vector<CPPTypeProxy *> Proxies;
Proxies _proxies;
};
#endif

View File

@ -1,53 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppUsing.cxx
* @author drose
* @date 1999-11-16
*/
#include "cppUsing.h"
#include "cppIdentifier.h"
/**
*
*/
CPPUsing::
CPPUsing(CPPIdentifier *ident, bool full_namespace, const CPPFile &file) :
CPPDeclaration(file),
_ident(ident), _full_namespace(full_namespace)
{
}
/**
*
*/
void CPPUsing::
output(std::ostream &out, int, CPPScope *, bool) const {
out << "using ";
if (_full_namespace) {
out << "namespace ";
}
out << *_ident;
}
/**
*
*/
CPPDeclaration::SubType CPPUsing::
get_subtype() const {
return ST_using;
}
/**
*
*/
CPPUsing *CPPUsing::
as_using() {
return this;
}

View File

@ -1,41 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppUsing.h
* @author drose
* @date 1999-11-16
*/
#ifndef CPPUSING_H
#define CPPUSING_H
#include "dtoolbase.h"
#include "cppDeclaration.h"
class CPPIdentifier;
class CPPScope;
/**
*
*/
class CPPUsing : public CPPDeclaration {
public:
CPPUsing(CPPIdentifier *ident, bool full_namespace, const CPPFile &file);
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const;
virtual SubType get_subtype() const;
virtual CPPUsing *as_using();
CPPIdentifier *_ident;
bool _full_namespace;
};
#endif

View File

@ -1,36 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cppVisibility.cxx
* @author drose
* @date 1999-10-22
*/
#include "cppVisibility.h"
std::ostream &
operator << (std::ostream &out, CPPVisibility vis) {
switch (vis) {
case V_published:
return out << "__published";
case V_public:
return out << "public";
case V_protected:
return out << "protected";
case V_private:
return out << "private";
case V_unknown:
return out << "unknown";
}
return out << "(**invalid visibility**)";
}

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