cppparser: Properly record C++11 attributes

This commit is contained in:
rdb 2022-10-24 00:33:23 +02:00
parent e3ec6f7947
commit dd262c6715
32 changed files with 5300 additions and 4931 deletions

View File

@ -1,4 +1,5 @@
set(P3CPPPARSER_HEADERS
cppAttributeList.h
cppArrayType.h cppBison.yxx cppBisonDefs.h
cppClassTemplateParameter.h cppCommentBlock.h
cppClosureType.h cppConstType.h
@ -17,6 +18,7 @@ set(P3CPPPARSER_HEADERS
)
set(P3CPPPARSER_SOURCES
cppAttributeList.cxx
cppArrayType.cxx ${CMAKE_CURRENT_BINARY_DIR}/cppBison.cxx
cppClassTemplateParameter.cxx
cppCommentBlock.cxx cppClosureType.cxx cppConstType.cxx cppDeclaration.cxx

View File

@ -189,6 +189,11 @@ output_instance(std::ostream &out, int indent_level, CPPScope *scope,
brackets << *_bounds;
}
brackets << "]";
if (!_attributes.is_empty()) {
brackets << " " << _attributes;
}
std::string bracketsstr = brackets.str();
_element_type->output_instance(out, indent_level, scope, complete,

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.3. */
/* 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-2020 Free Software Foundation,
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
@ -16,7 +16,7 @@
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 <http://www.gnu.org/licenses/>. */
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
@ -208,6 +208,7 @@ extern int cppyydebug;
typedef enum yytokentype yytoken_kind_t;
#endif
/* Token kinds. */
#define YYEMPTY -2
#define YYEOF 0
#define YYerror 256
#define YYUNDEF 257
@ -380,6 +381,8 @@ struct YYLTYPE
int cppyyparse (void);
#endif /* !YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED */

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
#include <string>
#include "cppAttributeList.h"
#include "cppClosureType.h"
#include "cppExtensionType.h"
#include "cppFile.h"
@ -65,6 +66,7 @@ extern CPPPreprocessor *current_lexer;
class cppyystype {
public:
std::string str;
CPPAttributeList attr_list;
union {
unsigned long long integer;
long double real;

View File

@ -152,6 +152,10 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) cons
out << " noexcept";
}
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
if (_return_type != nullptr) {
out << " -> ";
_return_type->output(out, indent_level, scope, false);

View File

@ -18,8 +18,9 @@
*
*/
CPPDeclaration::
CPPDeclaration(const CPPFile &file) :
_file(file)
CPPDeclaration(const CPPFile &file, CPPAttributeList attr) :
_file(file),
_attributes(std::move(attr))
{
_vis = V_unknown;
_template_scope = nullptr;
@ -34,7 +35,8 @@ CPPDeclaration(const CPPDeclaration &copy) :
_vis(copy._vis),
_template_scope(copy._template_scope),
_file(copy._file),
_leading_comment(copy._leading_comment)
_leading_comment(copy._leading_comment),
_attributes(copy._attributes)
{
}
@ -47,6 +49,7 @@ operator = (const CPPDeclaration &copy) {
_template_scope = copy._template_scope;
_file = copy._file;
_leading_comment = copy._leading_comment;
_attributes = copy._attributes;
return *this;
}
@ -135,6 +138,22 @@ substitute_decl(SubstDecl &subst, CPPScope *, CPPScope *) {
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;
}
/**
*
*/

View File

@ -19,6 +19,7 @@
#include "cppVisibility.h"
#include "cppFile.h"
#include "cppCommentBlock.h"
#include "cppAttributeList.h"
#include <string>
#include <vector>
@ -59,6 +60,9 @@ class CPPPreprocessor;
class CPPDeclaration {
public:
enum SubType {
// Empty declaration
ST_empty,
// Subtypes of CPPDeclaration
ST_instance,
ST_type_declaration,
@ -87,7 +91,7 @@ public:
ST_closure,
};
CPPDeclaration(const CPPFile &file);
CPPDeclaration(const CPPFile &file, CPPAttributeList attr = CPPAttributeList());
CPPDeclaration(const CPPDeclaration &copy);
virtual ~CPPDeclaration() {};
@ -114,9 +118,9 @@ public:
Instantiations _instantiations;
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
bool complete) const=0;
bool complete) const;
virtual SubType get_subtype() const=0;
virtual SubType get_subtype() const;
virtual CPPInstance *as_instance();
virtual CPPClassTemplateParameter *as_class_template_parameter();
@ -216,6 +220,7 @@ public:
CPPTemplateScope *_template_scope;
CPPFile _file;
CPPCommentBlock *_leading_comment;
CPPAttributeList _attributes;
protected:
virtual bool is_equal(const CPPDeclaration *other) const;

View File

@ -26,8 +26,8 @@
*/
CPPEnumType::
CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
CPPScope *scope, const CPPFile &file) :
CPPExtensionType(type, ident, current_scope, file),
CPPScope *scope, const CPPFile &file, CPPAttributeList attr) :
CPPExtensionType(type, ident, current_scope, file, std::move(attr)),
_scope(scope),
_element_type(nullptr),
_last_value(nullptr)
@ -44,8 +44,9 @@ CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
*/
CPPEnumType::
CPPEnumType(Type type, CPPIdentifier *ident, CPPType *element_type,
CPPScope *current_scope, CPPScope *scope, const CPPFile &file) :
CPPExtensionType(type, ident, current_scope, file),
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)
@ -89,7 +90,9 @@ get_underlying_type() {
*
*/
CPPInstance *CPPEnumType::
add_element(const std::string &name, CPPExpression *value, CPPPreprocessor *preprocessor, const cppyyltype &pos) {
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;
@ -102,6 +105,7 @@ add_element(const std::string &name, CPPExpression *value, CPPPreprocessor *prep
inst = new CPPInstance(this, ident);
}
inst->_storage_class |= CPPInstance::SC_constexpr;
inst->_attributes = std::move(attr);
_elements.push_back(inst);
if (value == nullptr) {
@ -269,9 +273,12 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) cons
out << _type << " ";
}
out << _ident->get_local_name(scope);
} else {
}
else {
out << _type;
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
if (_ident != nullptr) {
out << " " << _ident->get_local_name(scope);
}
@ -280,11 +287,15 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) cons
}
out << " {\n";
Elements::const_iterator ei;
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
indent(out, indent_level + 2) << (*ei)->get_local_name();
if ((*ei)->_initializer != nullptr) {
out << " = " << *(*ei)->_initializer;
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";
}

View File

@ -32,15 +32,18 @@ class CPPScope;
class CPPEnumType : public CPPExtensionType {
public:
CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
CPPScope *scope, const CPPFile &file);
CPPScope *scope, const CPPFile &file,
CPPAttributeList attr = CPPAttributeList());
CPPEnumType(Type type, CPPIdentifier *ident, CPPType *element_type,
CPPScope *current_scope, CPPScope *scope, const CPPFile &file);
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);
CPPPreprocessor *preprocessor, const cppyyltype &pos,
CPPAttributeList attr = CPPAttributeList());
virtual bool is_incomplete() const;

View File

@ -23,7 +23,7 @@
CPPExtensionType::
CPPExtensionType(CPPExtensionType::Type type,
CPPIdentifier *ident, CPPScope *current_scope,
const CPPFile &file) :
const CPPFile &file, CPPAttributeList attr) :
CPPType(file),
_type(type), _ident(ident),
_alignment(nullptr)
@ -31,6 +31,7 @@ CPPExtensionType(CPPExtensionType::Type type,
if (_ident != nullptr) {
_ident->_native_scope = current_scope;
}
_attributes = std::move(attr);
}
/**
@ -215,6 +216,9 @@ output(std::ostream &out, int, CPPScope *scope, bool complete) const {
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()) {

View File

@ -39,7 +39,7 @@ public:
};
CPPExtensionType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
const CPPFile &file);
const CPPFile &file, CPPAttributeList attr = CPPAttributeList());
virtual std::string get_simple_name() const;
virtual std::string get_local_name(CPPScope *scope = nullptr) const;

View File

@ -224,10 +224,13 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete,
if (_flags & F_override) {
out << " override";
}
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
out << " -> ";
_return_type->output(out, indent_level, scope, false);
} else {
}
else {
_return_type->output(out, indent_level, scope, complete);
out << "(";
_parameters->output(out, scope, true, num_default_parameters);
@ -244,6 +247,9 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete,
if (_flags & F_override) {
out << " override";
}
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
}
}
@ -278,8 +284,8 @@ output_instance(ostream &out, int indent_level, CPPScope *scope,
if (_flags & (F_constructor | F_destructor)) {
// No return type for constructors and destructors.
out << prename << name << str;
} else if (_flags & F_trailing_return_type) {
}
else if (_flags & F_trailing_return_type) {
// It was declared using trailing return type, so let's format it that
// way.
out << "auto ";
@ -291,12 +297,13 @@ output_instance(ostream &out, int indent_level, CPPScope *scope,
}
out << str;
} else if (_flags & F_operator_typecast) {
}
else if (_flags & F_operator_typecast) {
out << "operator ";
_return_type->output_instance(out, indent_level, scope, complete, "", prename + str);
} else {
_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);
@ -322,6 +329,10 @@ output_instance(ostream &out, int indent_level, CPPScope *scope,
out << " override";
}
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
if (_flags & F_trailing_return_type) {
out << " -> ";
_return_type->output(out, indent_level, scope, false);

View File

@ -84,6 +84,14 @@ add_name(const CPPNameComponent &name) {
_names.push_back(name);
}
/**
*
*/
void CPPIdentifier::
prepend(CPPIdentifier *ident) {
_names.insert(_names.begin(), ident->_names.begin(), ident->_names.end());
}
/**
*
*/

View File

@ -41,6 +41,8 @@ public:
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;

View File

@ -37,7 +37,6 @@ CPPInstance(CPPType *type, const string &name, int storage_class) :
_type(type),
_ident(new CPPIdentifier(name)),
_storage_class(storage_class),
_alignment(nullptr),
_bit_width(-1)
{
_initializer = nullptr;
@ -52,7 +51,6 @@ CPPInstance(CPPType *type, CPPIdentifier *ident, int storage_class) :
_type(type),
_ident(ident),
_storage_class(storage_class),
_alignment(nullptr),
_bit_width(-1)
{
_initializer = nullptr;
@ -66,11 +64,11 @@ CPPInstance(CPPType *type, CPPIdentifier *ident, int storage_class) :
CPPInstance::
CPPInstance(CPPType *type, CPPInstanceIdentifier *ii, int storage_class,
const CPPFile &file) :
CPPDeclaration(file),
_alignment(nullptr)
CPPDeclaration(file)
{
_type = ii->unroll_type(type);
_ident = ii->_ident;
_attributes = ii->_attributes;
ii->_ident = nullptr;
_storage_class = storage_class;
_initializer = nullptr;
@ -111,7 +109,6 @@ CPPInstance(const CPPInstance &copy) :
_ident(copy._ident),
_initializer(copy._initializer),
_storage_class(copy._storage_class),
_alignment(copy._alignment),
_bit_width(copy._bit_width)
{
assert(_type != nullptr);
@ -156,7 +153,7 @@ operator == (const CPPInstance &other) const {
if (_storage_class != other._storage_class) {
return false;
}
if (_alignment != other._alignment) {
if (_attributes != other._attributes) {
return false;
}
@ -200,8 +197,8 @@ operator < (const CPPInstance &other) const {
if (_storage_class != other._storage_class) {
return _storage_class < other._storage_class;
}
if (_alignment != other._alignment) {
return _alignment < other._alignment;
if (_attributes != other._attributes) {
return _attributes < other._attributes;
}
// We *do* care about the identifier. We need to differentiate types of
@ -264,7 +261,7 @@ set_initializer(CPPExpression *initializer) {
*/
void CPPInstance::
set_alignment(int align) {
_alignment = new CPPExpression(align);
_attributes.add_alignas(align);
}
/**
@ -274,7 +271,7 @@ set_alignment(int align) {
*/
void CPPInstance::
set_alignment(CPPExpression *const_expr) {
_alignment = const_expr;
_attributes.add_alignas(const_expr);
}
/**
@ -544,8 +541,8 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete,
indent(out, indent_level);
}
if (_alignment != nullptr) {
out << "alignas(" << *_alignment << ") ";
if (!_attributes.is_empty()) {
out << _attributes << " ";
}
if (_storage_class & SC_static) {
@ -600,8 +597,8 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete,
_type->as_function_type()->
output_instance(out, indent_level, scope, complete, "", name,
num_default_parameters);
} else {
}
else {
_type->output_instance(out, indent_level, scope, complete, "", name);
}
@ -623,7 +620,6 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete,
}
}
/**
*
*/

View File

@ -19,6 +19,7 @@
#include "cppDeclaration.h"
#include "cppType.h"
#include "cppTemplateParameterList.h"
#include "cppAttributeList.h"
class CPPInstanceIdentifier;
class CPPIdentifier;
@ -127,7 +128,6 @@ public:
CPPExpression *_initializer;
int _storage_class;
CPPExpression *_alignment;
int _bit_width;
private:

View File

@ -25,20 +25,22 @@
*
*/
CPPInstanceIdentifier::Modifier::
Modifier(CPPInstanceIdentifierType type) :
Modifier(CPPInstanceIdentifierType type, CPPAttributeList attr) :
_type(type),
_func_params(nullptr),
_func_flags(0),
_scoping(nullptr),
_expr(nullptr) {
_expr(nullptr),
_attributes(std::move(attr)) {
}
/**
*
*/
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
func_type(CPPParameterList *params, int flags, CPPType *trailing_return_type) {
Modifier mod(IIT_func);
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;
@ -49,8 +51,8 @@ func_type(CPPParameterList *params, int flags, CPPType *trailing_return_type) {
*
*/
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
array_type(CPPExpression *expr) {
Modifier mod(IIT_array);
array_type(CPPExpression *expr, CPPAttributeList attr) {
Modifier mod(IIT_array, std::move(attr));
mod._expr = expr;
return mod;
}
@ -59,8 +61,8 @@ array_type(CPPExpression *expr) {
*
*/
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
scoped_pointer_type(CPPIdentifier *scoping) {
Modifier mod(IIT_scoped_pointer);
scoped_pointer_type(CPPIdentifier *scoping, CPPAttributeList attr) {
Modifier mod(IIT_scoped_pointer, std::move(attr));
mod._scoping = scoping;
return mod;
}
@ -86,6 +88,17 @@ CPPInstanceIdentifier(CPPIdentifier *ident) :
_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
@ -103,15 +116,16 @@ unroll_type(CPPType *start_type) {
*
*/
void CPPInstanceIdentifier::
add_modifier(CPPInstanceIdentifierType type) {
_modifiers.push_back(Modifier(type));
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) {
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
@ -134,22 +148,22 @@ add_func_modifier(CPPParameterList *params, int flags, CPPType *trailing_return_
flags |= CPPFunctionType::F_trailing_return_type;
}
_modifiers.push_back(Modifier::func_type(params, flags, 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) {
_modifiers.push_back(Modifier::scoped_pointer_type(scoping));
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) {
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.
@ -158,7 +172,7 @@ add_array_modifier(CPPExpression *expr) {
_ident->_names.back().append_name("[]");
} else {
_modifiers.push_back(Modifier::array_type(expr));
_modifiers.push_back(Modifier::array_type(expr, std::move(attr)));
}
}
@ -187,6 +201,14 @@ add_trailing_return_type(CPPType *type) {
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:
@ -316,5 +338,7 @@ r_unroll_type(CPPType *start_type,
abort();
}
result->_attributes = mod._attributes;
return CPPType::new_type(result);
}

View File

@ -15,6 +15,7 @@
#define CPPINSTANCEIDENTIFIER_H
#include "dtoolbase.h"
#include "cppAttributeList.h"
#include <vector>
#include <string>
@ -48,18 +49,25 @@ enum CPPInstanceIdentifierType {
class CPPInstanceIdentifier {
public:
CPPInstanceIdentifier(CPPIdentifier *ident);
CPPInstanceIdentifier(CPPIdentifier *ident, CPPAttributeList attributes);
CPPType *unroll_type(CPPType *start_type);
void add_modifier(CPPInstanceIdentifierType type);
void add_modifier(CPPInstanceIdentifierType type,
CPPAttributeList attr = CPPAttributeList());
void add_func_modifier(CPPParameterList *params, int flags,
CPPType *trailing_return_type = nullptr);
void add_scoped_pointer_modifier(CPPIdentifier *scoping);
void add_array_modifier(CPPExpression *expr);
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,
@ -69,11 +77,14 @@ public:
class Modifier {
public:
Modifier(CPPInstanceIdentifierType type);
Modifier(CPPInstanceIdentifierType type,
CPPAttributeList attr = CPPAttributeList());
static Modifier func_type(CPPParameterList *params, int flags,
CPPType *trailing_return_type);
static Modifier array_type(CPPExpression *expr);
static Modifier scoped_pointer_type(CPPIdentifier *scoping);
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;
@ -82,10 +93,13 @@ public:
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;

View File

@ -20,8 +20,9 @@
*
*/
CPPNamespace::
CPPNamespace(CPPIdentifier *ident, CPPScope *scope, const CPPFile &file) :
CPPDeclaration(file),
CPPNamespace(CPPIdentifier *ident, CPPScope *scope, const CPPFile &file,
CPPAttributeList attr) :
CPPDeclaration(file, std::move(attr)),
_is_inline(false),
_ident(ident),
_scope(scope)
@ -77,15 +78,20 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) cons
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 {
}
else {
if (!_attributes.is_empty()) {
out << _attributes << " ";
}
if (_ident != nullptr) {
out << "namespace " << _ident->get_local_name(scope) << " {\n";
out << _ident->get_local_name(scope) << " {\n";
} else {
out << "namespace {\n";
out << "{\n";
}
_scope->write(out, indent_level + 2, _scope);

View File

@ -27,7 +27,7 @@ class CPPScope;
class CPPNamespace : public CPPDeclaration {
public:
CPPNamespace(CPPIdentifier *ident, CPPScope *scope,
const CPPFile &file);
const CPPFile &file, CPPAttributeList attr = CPPAttributeList());
std::string get_simple_name() const;
std::string get_local_name(CPPScope *scope = nullptr) const;

View File

@ -247,6 +247,12 @@ output_instance(std::ostream &out, int indent_level, CPPScope *scope,
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);
}

View File

@ -228,13 +228,16 @@ output_instance(std::ostream &out, int indent_level, CPPScope *scope,
bool complete, const std::string &prename,
const std::string &name) const {
if (_value_category == VC_rvalue) {
_pointing_at->output_instance(out, indent_level, scope, complete,
"&&" + prename, name);
} else {
_pointing_at->output_instance(out, indent_level, scope, complete,
"&" + prename, name);
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);
}
/**

View File

@ -41,8 +41,8 @@ output(std::ostream &out) const {
CPPStructType::
CPPStructType(CPPStructType::Type type, CPPIdentifier *ident,
CPPScope *current_scope, CPPScope *scope,
const CPPFile &file) :
CPPExtensionType(type, ident, current_scope, file),
const CPPFile &file, CPPAttributeList attr) :
CPPExtensionType(type, ident, current_scope, file, std::move(attr)),
_scope(scope),
_final(false)
{
@ -1261,10 +1261,14 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) cons
get_template_scope()->_parameters.write_formal(out, scope);
indent(out, indent_level);
}
out << _type;
if (!_attributes.is_empty()) {
out << " " << _attributes;
}
if (_ident != nullptr) {
out << _type << " " << _ident->get_local_name(scope);
} else {
out << _type;
out << " " << _ident->get_local_name(scope);
}
if (_final) {

View File

@ -35,7 +35,8 @@ public:
CPPStructType(Type type, CPPIdentifier *ident,
CPPScope *current_scope,
CPPScope *scope,
const CPPFile &file);
const CPPFile &file,
CPPAttributeList attr = CPPAttributeList());
CPPStructType(const CPPStructType &copy);
void operator = (const CPPStructType &copy);

View File

@ -43,7 +43,8 @@ CPPTypedefType(CPPType *type, const string &name, CPPScope *current_scope) :
*
*/
CPPTypedefType::
CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope) :
CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope,
CPPAttributeList attr) :
CPPType(CPPFile()),
_type(type),
_ident(ident),
@ -53,6 +54,8 @@ CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope) :
_ident->_native_scope = current_scope;
}
_subst_decl_recursive_protect = false;
_attributes = std::move(attr);
}
/**
@ -69,6 +72,7 @@ CPPTypedefType(CPPType *type, CPPInstanceIdentifier *ii,
assert(ii != nullptr);
_type = ii->unroll_type(type);
_ident = ii->_ident;
_attributes = std::move(ii->_attributes);
ii->_ident = nullptr;
delete ii;
@ -388,9 +392,16 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) cons
get_template_scope()->_parameters.write_formal(out, scope);
indent(out, indent_level);
}
out << "using " << name << " = ";
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);
}

View File

@ -28,7 +28,8 @@ class CPPInstanceIdentifier;
class CPPTypedefType : public CPPType {
public:
CPPTypedefType(CPPType *type, const std::string &name, CPPScope *current_scope);
CPPTypedefType(CPPType *type, CPPIdentifier *ident, 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);

View File

@ -1,4 +1,4 @@
#include "cppAttributeList.cxx"
#include "cppFunctionType.cxx"
#include "cppGlobals.cxx"
#include "cppCommentBlock.cxx"

View File

@ -47,8 +47,4 @@ namespace std {
typedef decltype(nullptr) nullptr_t;
}
// One day, we might extend interrogate to be able to parse this,
// but we currently don't need it.
#define alignas(x)
#endif