Merge remote-tracking branch 'upstream/master'
Conflicts:
makepanda/makepanda.py
This commit is contained in:
commit
f2b421e005
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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/) 
|
||||
[<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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
[](https://opencollective.com/panda3d)
|
||||
[](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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ dc_cleanup_parser() {
|
|||
# endif
|
||||
# endif
|
||||
|
||||
#include "dcParser.yxx.h"
|
||||
#include "dcParser.h"
|
||||
/* Symbol kind. */
|
||||
enum yysymbol_kind_t
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 << ")";
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ©) :
|
||||
CPPFunctionType(copy),
|
||||
_captures(copy._captures),
|
||||
_default_capture(copy._default_capture)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void CPPClosureType::
|
||||
operator = (const CPPClosureType ©) {
|
||||
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);
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
void operator = (const CPPClosureType ©);
|
||||
|
||||
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
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ©) :
|
||||
_vis(copy._vis),
|
||||
_template_scope(copy._template_scope),
|
||||
_file(copy._file),
|
||||
_leading_comment(copy._leading_comment),
|
||||
_attributes(copy._attributes)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CPPDeclaration &CPPDeclaration::
|
||||
operator = (const CPPDeclaration ©) {
|
||||
_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;
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
virtual ~CPPDeclaration() {};
|
||||
|
||||
CPPDeclaration &operator = (const CPPDeclaration ©);
|
||||
|
||||
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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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***";
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ©) :
|
||||
CPPType(copy),
|
||||
_return_type(copy._return_type),
|
||||
_parameters(copy._parameters),
|
||||
_flags(copy._flags),
|
||||
_class_owner(copy._class_owner)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void CPPFunctionType::
|
||||
operator = (const CPPFunctionType ©) {
|
||||
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 ¶ms = _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;
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
void operator = (const CPPFunctionType ©);
|
||||
|
||||
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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ©) :
|
||||
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;
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
~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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ¯o, 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 ¶meter_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 ¶meter_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;
|
||||
}
|
||||
|
|
@ -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 ¯o, 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 ¶meter_names);
|
||||
void save_expansion(Expansion &expansion, const std::string &exp,
|
||||
const vector_string ¶meter_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
|
||||
|
|
@ -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 << " >";
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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 ©);
|
||||
void operator = (const CPPStructType ©);
|
||||
|
||||
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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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; */
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
Loading…
Reference in New Issue