mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
cppparser: Properly record C++11 attributes
This commit is contained in:
parent
e3ec6f7947
commit
dd262c6715
@ -1,4 +1,5 @@
|
|||||||
set(P3CPPPARSER_HEADERS
|
set(P3CPPPARSER_HEADERS
|
||||||
|
cppAttributeList.h
|
||||||
cppArrayType.h cppBison.yxx cppBisonDefs.h
|
cppArrayType.h cppBison.yxx cppBisonDefs.h
|
||||||
cppClassTemplateParameter.h cppCommentBlock.h
|
cppClassTemplateParameter.h cppCommentBlock.h
|
||||||
cppClosureType.h cppConstType.h
|
cppClosureType.h cppConstType.h
|
||||||
@ -17,6 +18,7 @@ set(P3CPPPARSER_HEADERS
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(P3CPPPARSER_SOURCES
|
set(P3CPPPARSER_SOURCES
|
||||||
|
cppAttributeList.cxx
|
||||||
cppArrayType.cxx ${CMAKE_CURRENT_BINARY_DIR}/cppBison.cxx
|
cppArrayType.cxx ${CMAKE_CURRENT_BINARY_DIR}/cppBison.cxx
|
||||||
cppClassTemplateParameter.cxx
|
cppClassTemplateParameter.cxx
|
||||||
cppCommentBlock.cxx cppClosureType.cxx cppConstType.cxx cppDeclaration.cxx
|
cppCommentBlock.cxx cppClosureType.cxx cppConstType.cxx cppDeclaration.cxx
|
||||||
|
@ -189,6 +189,11 @@ output_instance(std::ostream &out, int indent_level, CPPScope *scope,
|
|||||||
brackets << *_bounds;
|
brackets << *_bounds;
|
||||||
}
|
}
|
||||||
brackets << "]";
|
brackets << "]";
|
||||||
|
|
||||||
|
if (!_attributes.is_empty()) {
|
||||||
|
brackets << " " << _attributes;
|
||||||
|
}
|
||||||
|
|
||||||
std::string bracketsstr = brackets.str();
|
std::string bracketsstr = brackets.str();
|
||||||
|
|
||||||
_element_type->output_instance(out, indent_level, scope, complete,
|
_element_type->output_instance(out, indent_level, scope, complete,
|
||||||
|
196
dtool/src/cppparser/cppAttributeList.cxx
Normal file
196
dtool/src/cppparser/cppAttributeList.cxx
Normal 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 << ")";
|
||||||
|
}
|
||||||
|
}
|
65
dtool/src/cppparser/cppAttributeList.h
Normal file
65
dtool/src/cppparser/cppAttributeList.h
Normal 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
@ -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
|
/* 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.
|
Inc.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@ -16,7 +16,7 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
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
|
/* As a special exception, you may create a larger work that contains
|
||||||
part or all of the Bison parser skeleton and distribute that work
|
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;
|
typedef enum yytokentype yytoken_kind_t;
|
||||||
#endif
|
#endif
|
||||||
/* Token kinds. */
|
/* Token kinds. */
|
||||||
|
#define YYEMPTY -2
|
||||||
#define YYEOF 0
|
#define YYEOF 0
|
||||||
#define YYerror 256
|
#define YYerror 256
|
||||||
#define YYUNDEF 257
|
#define YYUNDEF 257
|
||||||
@ -380,6 +381,8 @@ struct YYLTYPE
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cppyyparse (void);
|
int cppyyparse (void);
|
||||||
|
|
||||||
|
|
||||||
#endif /* !YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED */
|
#endif /* !YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "cppAttributeList.h"
|
||||||
#include "cppClosureType.h"
|
#include "cppClosureType.h"
|
||||||
#include "cppExtensionType.h"
|
#include "cppExtensionType.h"
|
||||||
#include "cppFile.h"
|
#include "cppFile.h"
|
||||||
@ -65,6 +66,7 @@ extern CPPPreprocessor *current_lexer;
|
|||||||
class cppyystype {
|
class cppyystype {
|
||||||
public:
|
public:
|
||||||
std::string str;
|
std::string str;
|
||||||
|
CPPAttributeList attr_list;
|
||||||
union {
|
union {
|
||||||
unsigned long long integer;
|
unsigned long long integer;
|
||||||
long double real;
|
long double real;
|
||||||
|
@ -152,6 +152,10 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) cons
|
|||||||
out << " noexcept";
|
out << " noexcept";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_attributes.is_empty()) {
|
||||||
|
out << " " << _attributes;
|
||||||
|
}
|
||||||
|
|
||||||
if (_return_type != nullptr) {
|
if (_return_type != nullptr) {
|
||||||
out << " -> ";
|
out << " -> ";
|
||||||
_return_type->output(out, indent_level, scope, false);
|
_return_type->output(out, indent_level, scope, false);
|
||||||
|
@ -18,8 +18,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
CPPDeclaration::
|
CPPDeclaration::
|
||||||
CPPDeclaration(const CPPFile &file) :
|
CPPDeclaration(const CPPFile &file, CPPAttributeList attr) :
|
||||||
_file(file)
|
_file(file),
|
||||||
|
_attributes(std::move(attr))
|
||||||
{
|
{
|
||||||
_vis = V_unknown;
|
_vis = V_unknown;
|
||||||
_template_scope = nullptr;
|
_template_scope = nullptr;
|
||||||
@ -34,7 +35,8 @@ CPPDeclaration(const CPPDeclaration ©) :
|
|||||||
_vis(copy._vis),
|
_vis(copy._vis),
|
||||||
_template_scope(copy._template_scope),
|
_template_scope(copy._template_scope),
|
||||||
_file(copy._file),
|
_file(copy._file),
|
||||||
_leading_comment(copy._leading_comment)
|
_leading_comment(copy._leading_comment),
|
||||||
|
_attributes(copy._attributes)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +49,7 @@ operator = (const CPPDeclaration ©) {
|
|||||||
_template_scope = copy._template_scope;
|
_template_scope = copy._template_scope;
|
||||||
_file = copy._file;
|
_file = copy._file;
|
||||||
_leading_comment = copy._leading_comment;
|
_leading_comment = copy._leading_comment;
|
||||||
|
_attributes = copy._attributes;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +138,22 @@ substitute_decl(SubstDecl &subst, CPPScope *, CPPScope *) {
|
|||||||
return this;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "cppVisibility.h"
|
#include "cppVisibility.h"
|
||||||
#include "cppFile.h"
|
#include "cppFile.h"
|
||||||
#include "cppCommentBlock.h"
|
#include "cppCommentBlock.h"
|
||||||
|
#include "cppAttributeList.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -59,6 +60,9 @@ class CPPPreprocessor;
|
|||||||
class CPPDeclaration {
|
class CPPDeclaration {
|
||||||
public:
|
public:
|
||||||
enum SubType {
|
enum SubType {
|
||||||
|
// Empty declaration
|
||||||
|
ST_empty,
|
||||||
|
|
||||||
// Subtypes of CPPDeclaration
|
// Subtypes of CPPDeclaration
|
||||||
ST_instance,
|
ST_instance,
|
||||||
ST_type_declaration,
|
ST_type_declaration,
|
||||||
@ -87,7 +91,7 @@ public:
|
|||||||
ST_closure,
|
ST_closure,
|
||||||
};
|
};
|
||||||
|
|
||||||
CPPDeclaration(const CPPFile &file);
|
CPPDeclaration(const CPPFile &file, CPPAttributeList attr = CPPAttributeList());
|
||||||
CPPDeclaration(const CPPDeclaration ©);
|
CPPDeclaration(const CPPDeclaration ©);
|
||||||
virtual ~CPPDeclaration() {};
|
virtual ~CPPDeclaration() {};
|
||||||
|
|
||||||
@ -114,9 +118,9 @@ public:
|
|||||||
Instantiations _instantiations;
|
Instantiations _instantiations;
|
||||||
|
|
||||||
virtual void output(std::ostream &out, int indent_level, CPPScope *scope,
|
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 CPPInstance *as_instance();
|
||||||
virtual CPPClassTemplateParameter *as_class_template_parameter();
|
virtual CPPClassTemplateParameter *as_class_template_parameter();
|
||||||
@ -216,6 +220,7 @@ public:
|
|||||||
CPPTemplateScope *_template_scope;
|
CPPTemplateScope *_template_scope;
|
||||||
CPPFile _file;
|
CPPFile _file;
|
||||||
CPPCommentBlock *_leading_comment;
|
CPPCommentBlock *_leading_comment;
|
||||||
|
CPPAttributeList _attributes;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool is_equal(const CPPDeclaration *other) const;
|
virtual bool is_equal(const CPPDeclaration *other) const;
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
*/
|
*/
|
||||||
CPPEnumType::
|
CPPEnumType::
|
||||||
CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
|
CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
|
||||||
CPPScope *scope, const CPPFile &file) :
|
CPPScope *scope, const CPPFile &file, CPPAttributeList attr) :
|
||||||
CPPExtensionType(type, ident, current_scope, file),
|
CPPExtensionType(type, ident, current_scope, file, std::move(attr)),
|
||||||
_scope(scope),
|
_scope(scope),
|
||||||
_element_type(nullptr),
|
_element_type(nullptr),
|
||||||
_last_value(nullptr)
|
_last_value(nullptr)
|
||||||
@ -44,8 +44,9 @@ CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
|
|||||||
*/
|
*/
|
||||||
CPPEnumType::
|
CPPEnumType::
|
||||||
CPPEnumType(Type type, CPPIdentifier *ident, CPPType *element_type,
|
CPPEnumType(Type type, CPPIdentifier *ident, CPPType *element_type,
|
||||||
CPPScope *current_scope, CPPScope *scope, const CPPFile &file) :
|
CPPScope *current_scope, CPPScope *scope, const CPPFile &file,
|
||||||
CPPExtensionType(type, ident, current_scope, file),
|
CPPAttributeList attr) :
|
||||||
|
CPPExtensionType(type, ident, current_scope, file, std::move(attr)),
|
||||||
_scope(scope),
|
_scope(scope),
|
||||||
_element_type(element_type),
|
_element_type(element_type),
|
||||||
_last_value(nullptr)
|
_last_value(nullptr)
|
||||||
@ -89,7 +90,9 @@ get_underlying_type() {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
CPPInstance *CPPEnumType::
|
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);
|
CPPIdentifier *ident = new CPPIdentifier(name);
|
||||||
ident->_native_scope = _parent_scope;
|
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 = new CPPInstance(this, ident);
|
||||||
}
|
}
|
||||||
inst->_storage_class |= CPPInstance::SC_constexpr;
|
inst->_storage_class |= CPPInstance::SC_constexpr;
|
||||||
|
inst->_attributes = std::move(attr);
|
||||||
_elements.push_back(inst);
|
_elements.push_back(inst);
|
||||||
|
|
||||||
if (value == nullptr) {
|
if (value == nullptr) {
|
||||||
@ -269,9 +273,12 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) cons
|
|||||||
out << _type << " ";
|
out << _type << " ";
|
||||||
}
|
}
|
||||||
out << _ident->get_local_name(scope);
|
out << _ident->get_local_name(scope);
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
out << _type;
|
out << _type;
|
||||||
|
if (!_attributes.is_empty()) {
|
||||||
|
out << " " << _attributes;
|
||||||
|
}
|
||||||
if (_ident != nullptr) {
|
if (_ident != nullptr) {
|
||||||
out << " " << _ident->get_local_name(scope);
|
out << " " << _ident->get_local_name(scope);
|
||||||
}
|
}
|
||||||
@ -280,11 +287,15 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
out << " {\n";
|
out << " {\n";
|
||||||
Elements::const_iterator ei;
|
for (CPPInstance *element : _elements) {
|
||||||
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
|
indent(out, indent_level + 2) << element->get_local_name();
|
||||||
indent(out, indent_level + 2) << (*ei)->get_local_name();
|
|
||||||
if ((*ei)->_initializer != nullptr) {
|
if (!element->_attributes.is_empty()) {
|
||||||
out << " = " << *(*ei)->_initializer;
|
out << " " << element->_attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element->_initializer != nullptr) {
|
||||||
|
out << " = " << *element->_initializer;
|
||||||
}
|
}
|
||||||
out << ",\n";
|
out << ",\n";
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,18 @@ class CPPScope;
|
|||||||
class CPPEnumType : public CPPExtensionType {
|
class CPPEnumType : public CPPExtensionType {
|
||||||
public:
|
public:
|
||||||
CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
|
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,
|
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;
|
bool is_scoped() const;
|
||||||
CPPType *get_underlying_type();
|
CPPType *get_underlying_type();
|
||||||
|
|
||||||
CPPInstance *add_element(const std::string &name, CPPExpression *value,
|
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;
|
virtual bool is_incomplete() const;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
CPPExtensionType::
|
CPPExtensionType::
|
||||||
CPPExtensionType(CPPExtensionType::Type type,
|
CPPExtensionType(CPPExtensionType::Type type,
|
||||||
CPPIdentifier *ident, CPPScope *current_scope,
|
CPPIdentifier *ident, CPPScope *current_scope,
|
||||||
const CPPFile &file) :
|
const CPPFile &file, CPPAttributeList attr) :
|
||||||
CPPType(file),
|
CPPType(file),
|
||||||
_type(type), _ident(ident),
|
_type(type), _ident(ident),
|
||||||
_alignment(nullptr)
|
_alignment(nullptr)
|
||||||
@ -31,6 +31,7 @@ CPPExtensionType(CPPExtensionType::Type type,
|
|||||||
if (_ident != nullptr) {
|
if (_ident != nullptr) {
|
||||||
_ident->_native_scope = current_scope;
|
_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) {
|
if (complete || cppparser_output_class_keyword) {
|
||||||
out << _type << " ";
|
out << _type << " ";
|
||||||
}
|
}
|
||||||
|
if (complete && !_attributes.is_empty()) {
|
||||||
|
out << _attributes << " ";
|
||||||
|
}
|
||||||
out << _ident->get_local_name(scope);
|
out << _ident->get_local_name(scope);
|
||||||
|
|
||||||
} else if (!_typedefs.empty()) {
|
} else if (!_typedefs.empty()) {
|
||||||
|
@ -39,7 +39,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
CPPExtensionType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
|
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_simple_name() const;
|
||||||
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
|
virtual std::string get_local_name(CPPScope *scope = nullptr) const;
|
||||||
|
@ -224,10 +224,13 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete,
|
|||||||
if (_flags & F_override) {
|
if (_flags & F_override) {
|
||||||
out << " override";
|
out << " override";
|
||||||
}
|
}
|
||||||
|
if (!_attributes.is_empty()) {
|
||||||
|
out << " " << _attributes;
|
||||||
|
}
|
||||||
out << " -> ";
|
out << " -> ";
|
||||||
_return_type->output(out, indent_level, scope, false);
|
_return_type->output(out, indent_level, scope, false);
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
_return_type->output(out, indent_level, scope, complete);
|
_return_type->output(out, indent_level, scope, complete);
|
||||||
out << "(";
|
out << "(";
|
||||||
_parameters->output(out, scope, true, num_default_parameters);
|
_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) {
|
if (_flags & F_override) {
|
||||||
out << " 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)) {
|
if (_flags & (F_constructor | F_destructor)) {
|
||||||
// No return type for constructors and destructors.
|
// No return type for constructors and destructors.
|
||||||
out << prename << name << str;
|
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
|
// It was declared using trailing return type, so let's format it that
|
||||||
// way.
|
// way.
|
||||||
out << "auto ";
|
out << "auto ";
|
||||||
@ -291,12 +297,13 @@ output_instance(ostream &out, int indent_level, CPPScope *scope,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out << str;
|
out << str;
|
||||||
|
}
|
||||||
} else if (_flags & F_operator_typecast) {
|
else if (_flags & F_operator_typecast) {
|
||||||
out << "operator ";
|
out << "operator ";
|
||||||
_return_type->output_instance(out, indent_level, scope, complete, "", prename + str);
|
_return_type->output_instance(out, indent_level, scope, complete,
|
||||||
|
"", prename + str);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (prename.empty()) {
|
if (prename.empty()) {
|
||||||
_return_type->output_instance(out, indent_level, scope, complete,
|
_return_type->output_instance(out, indent_level, scope, complete,
|
||||||
"", prename + name + str);
|
"", prename + name + str);
|
||||||
@ -322,6 +329,10 @@ output_instance(ostream &out, int indent_level, CPPScope *scope,
|
|||||||
out << " override";
|
out << " override";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_attributes.is_empty()) {
|
||||||
|
out << " " << _attributes;
|
||||||
|
}
|
||||||
|
|
||||||
if (_flags & F_trailing_return_type) {
|
if (_flags & F_trailing_return_type) {
|
||||||
out << " -> ";
|
out << " -> ";
|
||||||
_return_type->output(out, indent_level, scope, false);
|
_return_type->output(out, indent_level, scope, false);
|
||||||
|
@ -84,6 +84,14 @@ add_name(const CPPNameComponent &name) {
|
|||||||
_names.push_back(name);
|
_names.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void CPPIdentifier::
|
||||||
|
prepend(CPPIdentifier *ident) {
|
||||||
|
_names.insert(_names.begin(), ident->_names.begin(), ident->_names.end());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +41,8 @@ public:
|
|||||||
void add_name(const std::string &name);
|
void add_name(const std::string &name);
|
||||||
void add_name(const CPPNameComponent &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 operator != (const CPPIdentifier &other) const;
|
||||||
bool operator < (const CPPIdentifier &other) const;
|
bool operator < (const CPPIdentifier &other) const;
|
||||||
|
@ -37,7 +37,6 @@ CPPInstance(CPPType *type, const string &name, int storage_class) :
|
|||||||
_type(type),
|
_type(type),
|
||||||
_ident(new CPPIdentifier(name)),
|
_ident(new CPPIdentifier(name)),
|
||||||
_storage_class(storage_class),
|
_storage_class(storage_class),
|
||||||
_alignment(nullptr),
|
|
||||||
_bit_width(-1)
|
_bit_width(-1)
|
||||||
{
|
{
|
||||||
_initializer = nullptr;
|
_initializer = nullptr;
|
||||||
@ -52,7 +51,6 @@ CPPInstance(CPPType *type, CPPIdentifier *ident, int storage_class) :
|
|||||||
_type(type),
|
_type(type),
|
||||||
_ident(ident),
|
_ident(ident),
|
||||||
_storage_class(storage_class),
|
_storage_class(storage_class),
|
||||||
_alignment(nullptr),
|
|
||||||
_bit_width(-1)
|
_bit_width(-1)
|
||||||
{
|
{
|
||||||
_initializer = nullptr;
|
_initializer = nullptr;
|
||||||
@ -66,11 +64,11 @@ CPPInstance(CPPType *type, CPPIdentifier *ident, int storage_class) :
|
|||||||
CPPInstance::
|
CPPInstance::
|
||||||
CPPInstance(CPPType *type, CPPInstanceIdentifier *ii, int storage_class,
|
CPPInstance(CPPType *type, CPPInstanceIdentifier *ii, int storage_class,
|
||||||
const CPPFile &file) :
|
const CPPFile &file) :
|
||||||
CPPDeclaration(file),
|
CPPDeclaration(file)
|
||||||
_alignment(nullptr)
|
|
||||||
{
|
{
|
||||||
_type = ii->unroll_type(type);
|
_type = ii->unroll_type(type);
|
||||||
_ident = ii->_ident;
|
_ident = ii->_ident;
|
||||||
|
_attributes = ii->_attributes;
|
||||||
ii->_ident = nullptr;
|
ii->_ident = nullptr;
|
||||||
_storage_class = storage_class;
|
_storage_class = storage_class;
|
||||||
_initializer = nullptr;
|
_initializer = nullptr;
|
||||||
@ -111,7 +109,6 @@ CPPInstance(const CPPInstance ©) :
|
|||||||
_ident(copy._ident),
|
_ident(copy._ident),
|
||||||
_initializer(copy._initializer),
|
_initializer(copy._initializer),
|
||||||
_storage_class(copy._storage_class),
|
_storage_class(copy._storage_class),
|
||||||
_alignment(copy._alignment),
|
|
||||||
_bit_width(copy._bit_width)
|
_bit_width(copy._bit_width)
|
||||||
{
|
{
|
||||||
assert(_type != nullptr);
|
assert(_type != nullptr);
|
||||||
@ -156,7 +153,7 @@ operator == (const CPPInstance &other) const {
|
|||||||
if (_storage_class != other._storage_class) {
|
if (_storage_class != other._storage_class) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_alignment != other._alignment) {
|
if (_attributes != other._attributes) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,8 +197,8 @@ operator < (const CPPInstance &other) const {
|
|||||||
if (_storage_class != other._storage_class) {
|
if (_storage_class != other._storage_class) {
|
||||||
return _storage_class < other._storage_class;
|
return _storage_class < other._storage_class;
|
||||||
}
|
}
|
||||||
if (_alignment != other._alignment) {
|
if (_attributes != other._attributes) {
|
||||||
return _alignment < other._alignment;
|
return _attributes < other._attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We *do* care about the identifier. We need to differentiate types of
|
// We *do* care about the identifier. We need to differentiate types of
|
||||||
@ -264,7 +261,7 @@ set_initializer(CPPExpression *initializer) {
|
|||||||
*/
|
*/
|
||||||
void CPPInstance::
|
void CPPInstance::
|
||||||
set_alignment(int align) {
|
set_alignment(int align) {
|
||||||
_alignment = new CPPExpression(align);
|
_attributes.add_alignas(align);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -274,7 +271,7 @@ set_alignment(int align) {
|
|||||||
*/
|
*/
|
||||||
void CPPInstance::
|
void CPPInstance::
|
||||||
set_alignment(CPPExpression *const_expr) {
|
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);
|
indent(out, indent_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_alignment != nullptr) {
|
if (!_attributes.is_empty()) {
|
||||||
out << "alignas(" << *_alignment << ") ";
|
out << _attributes << " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_storage_class & SC_static) {
|
if (_storage_class & SC_static) {
|
||||||
@ -600,8 +597,8 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete,
|
|||||||
_type->as_function_type()->
|
_type->as_function_type()->
|
||||||
output_instance(out, indent_level, scope, complete, "", name,
|
output_instance(out, indent_level, scope, complete, "", name,
|
||||||
num_default_parameters);
|
num_default_parameters);
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
_type->output_instance(out, indent_level, scope, complete, "", name);
|
_type->output_instance(out, indent_level, scope, complete, "", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,7 +620,6 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "cppDeclaration.h"
|
#include "cppDeclaration.h"
|
||||||
#include "cppType.h"
|
#include "cppType.h"
|
||||||
#include "cppTemplateParameterList.h"
|
#include "cppTemplateParameterList.h"
|
||||||
|
#include "cppAttributeList.h"
|
||||||
|
|
||||||
class CPPInstanceIdentifier;
|
class CPPInstanceIdentifier;
|
||||||
class CPPIdentifier;
|
class CPPIdentifier;
|
||||||
@ -127,7 +128,6 @@ public:
|
|||||||
CPPExpression *_initializer;
|
CPPExpression *_initializer;
|
||||||
|
|
||||||
int _storage_class;
|
int _storage_class;
|
||||||
CPPExpression *_alignment;
|
|
||||||
int _bit_width;
|
int _bit_width;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -25,20 +25,22 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
CPPInstanceIdentifier::Modifier::
|
CPPInstanceIdentifier::Modifier::
|
||||||
Modifier(CPPInstanceIdentifierType type) :
|
Modifier(CPPInstanceIdentifierType type, CPPAttributeList attr) :
|
||||||
_type(type),
|
_type(type),
|
||||||
_func_params(nullptr),
|
_func_params(nullptr),
|
||||||
_func_flags(0),
|
_func_flags(0),
|
||||||
_scoping(nullptr),
|
_scoping(nullptr),
|
||||||
_expr(nullptr) {
|
_expr(nullptr),
|
||||||
|
_attributes(std::move(attr)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
|
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
|
||||||
func_type(CPPParameterList *params, int flags, CPPType *trailing_return_type) {
|
func_type(CPPParameterList *params, int flags, CPPType *trailing_return_type,
|
||||||
Modifier mod(IIT_func);
|
CPPAttributeList attr) {
|
||||||
|
Modifier mod(IIT_func, std::move(attr));
|
||||||
mod._func_params = params;
|
mod._func_params = params;
|
||||||
mod._func_flags = flags;
|
mod._func_flags = flags;
|
||||||
mod._trailing_return_type = trailing_return_type;
|
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::
|
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
|
||||||
array_type(CPPExpression *expr) {
|
array_type(CPPExpression *expr, CPPAttributeList attr) {
|
||||||
Modifier mod(IIT_array);
|
Modifier mod(IIT_array, std::move(attr));
|
||||||
mod._expr = expr;
|
mod._expr = expr;
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
@ -59,8 +61,8 @@ array_type(CPPExpression *expr) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
|
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
|
||||||
scoped_pointer_type(CPPIdentifier *scoping) {
|
scoped_pointer_type(CPPIdentifier *scoping, CPPAttributeList attr) {
|
||||||
Modifier mod(IIT_scoped_pointer);
|
Modifier mod(IIT_scoped_pointer, std::move(attr));
|
||||||
mod._scoping = scoping;
|
mod._scoping = scoping;
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
@ -86,6 +88,17 @@ CPPInstanceIdentifier(CPPIdentifier *ident) :
|
|||||||
_packed(false) {
|
_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
|
* Unrolls the list of type punctuation on either side of the identifier to
|
||||||
* determine the actual type represented by the identifier, given the
|
* determine the actual type represented by the identifier, given the
|
||||||
@ -103,15 +116,16 @@ unroll_type(CPPType *start_type) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void CPPInstanceIdentifier::
|
void CPPInstanceIdentifier::
|
||||||
add_modifier(CPPInstanceIdentifierType type) {
|
add_modifier(CPPInstanceIdentifierType type, CPPAttributeList attr) {
|
||||||
_modifiers.push_back(Modifier(type));
|
_modifiers.push_back(Modifier(type, std::move(attr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void CPPInstanceIdentifier::
|
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,
|
// 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
|
// 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
|
// 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;
|
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::
|
void CPPInstanceIdentifier::
|
||||||
add_scoped_pointer_modifier(CPPIdentifier *scoping) {
|
add_scoped_pointer_modifier(CPPIdentifier *scoping, CPPAttributeList attr) {
|
||||||
_modifiers.push_back(Modifier::scoped_pointer_type(scoping));
|
_modifiers.push_back(Modifier::scoped_pointer_type(scoping, std::move(attr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void CPPInstanceIdentifier::
|
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
|
// 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
|
// array modifier to them, but appending [] to the identifier. This is to
|
||||||
// work around a parser ambiguity.
|
// work around a parser ambiguity.
|
||||||
@ -158,7 +172,7 @@ add_array_modifier(CPPExpression *expr) {
|
|||||||
|
|
||||||
_ident->_names.back().append_name("[]");
|
_ident->_names.back().append_name("[]");
|
||||||
} else {
|
} 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";
|
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
|
* Returns the initializer parameter list that was set for this particular
|
||||||
* instance, e.g. if the instance were:
|
* instance, e.g. if the instance were:
|
||||||
@ -316,5 +338,7 @@ r_unroll_type(CPPType *start_type,
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result->_attributes = mod._attributes;
|
||||||
|
|
||||||
return CPPType::new_type(result);
|
return CPPType::new_type(result);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#define CPPINSTANCEIDENTIFIER_H
|
#define CPPINSTANCEIDENTIFIER_H
|
||||||
|
|
||||||
#include "dtoolbase.h"
|
#include "dtoolbase.h"
|
||||||
|
#include "cppAttributeList.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -48,18 +49,25 @@ enum CPPInstanceIdentifierType {
|
|||||||
class CPPInstanceIdentifier {
|
class CPPInstanceIdentifier {
|
||||||
public:
|
public:
|
||||||
CPPInstanceIdentifier(CPPIdentifier *ident);
|
CPPInstanceIdentifier(CPPIdentifier *ident);
|
||||||
|
CPPInstanceIdentifier(CPPIdentifier *ident, CPPAttributeList attributes);
|
||||||
|
|
||||||
CPPType *unroll_type(CPPType *start_type);
|
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,
|
void add_func_modifier(CPPParameterList *params, int flags,
|
||||||
CPPType *trailing_return_type = nullptr);
|
CPPType *trailing_return_type = nullptr,
|
||||||
void add_scoped_pointer_modifier(CPPIdentifier *scoping);
|
CPPAttributeList attr = CPPAttributeList());
|
||||||
void add_array_modifier(CPPExpression *expr);
|
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_initializer_modifier(CPPParameterList *params);
|
||||||
|
|
||||||
void add_trailing_return_type(CPPType *type);
|
void add_trailing_return_type(CPPType *type);
|
||||||
|
|
||||||
|
void add_attributes(const CPPAttributeList &attributes);
|
||||||
|
|
||||||
CPPParameterList *get_initializer() const;
|
CPPParameterList *get_initializer() const;
|
||||||
|
|
||||||
CPPScope *get_scope(CPPScope *current_scope, CPPScope *global_scope,
|
CPPScope *get_scope(CPPScope *current_scope, CPPScope *global_scope,
|
||||||
@ -69,11 +77,14 @@ public:
|
|||||||
|
|
||||||
class Modifier {
|
class Modifier {
|
||||||
public:
|
public:
|
||||||
Modifier(CPPInstanceIdentifierType type);
|
Modifier(CPPInstanceIdentifierType type,
|
||||||
|
CPPAttributeList attr = CPPAttributeList());
|
||||||
static Modifier func_type(CPPParameterList *params, int flags,
|
static Modifier func_type(CPPParameterList *params, int flags,
|
||||||
CPPType *trailing_return_type);
|
CPPType *trailing_return_type,
|
||||||
static Modifier array_type(CPPExpression *expr);
|
CPPAttributeList attr);
|
||||||
static Modifier scoped_pointer_type(CPPIdentifier *scoping);
|
static Modifier array_type(CPPExpression *expr, CPPAttributeList attr);
|
||||||
|
static Modifier scoped_pointer_type(CPPIdentifier *scoping,
|
||||||
|
CPPAttributeList attr);
|
||||||
static Modifier initializer_type(CPPParameterList *params);
|
static Modifier initializer_type(CPPParameterList *params);
|
||||||
|
|
||||||
CPPInstanceIdentifierType _type;
|
CPPInstanceIdentifierType _type;
|
||||||
@ -82,10 +93,13 @@ public:
|
|||||||
CPPIdentifier *_scoping;
|
CPPIdentifier *_scoping;
|
||||||
CPPExpression *_expr;
|
CPPExpression *_expr;
|
||||||
CPPType *_trailing_return_type;
|
CPPType *_trailing_return_type;
|
||||||
|
CPPAttributeList _attributes;
|
||||||
};
|
};
|
||||||
typedef std::vector<Modifier> Modifiers;
|
typedef std::vector<Modifier> Modifiers;
|
||||||
Modifiers _modifiers;
|
Modifiers _modifiers;
|
||||||
|
|
||||||
|
CPPAttributeList _attributes;
|
||||||
|
|
||||||
// If not null, indicates a bitfield
|
// If not null, indicates a bitfield
|
||||||
CPPExpression *_bit_width;
|
CPPExpression *_bit_width;
|
||||||
|
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
CPPNamespace::
|
CPPNamespace::
|
||||||
CPPNamespace(CPPIdentifier *ident, CPPScope *scope, const CPPFile &file) :
|
CPPNamespace(CPPIdentifier *ident, CPPScope *scope, const CPPFile &file,
|
||||||
CPPDeclaration(file),
|
CPPAttributeList attr) :
|
||||||
|
CPPDeclaration(file, std::move(attr)),
|
||||||
_is_inline(false),
|
_is_inline(false),
|
||||||
_ident(ident),
|
_ident(ident),
|
||||||
_scope(scope)
|
_scope(scope)
|
||||||
@ -77,15 +78,20 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) cons
|
|||||||
if (_is_inline) {
|
if (_is_inline) {
|
||||||
out << "inline ";
|
out << "inline ";
|
||||||
}
|
}
|
||||||
|
out << "namespace ";
|
||||||
|
|
||||||
if (!complete && _ident != nullptr) {
|
if (!complete && _ident != nullptr) {
|
||||||
// If we have a name, use it.
|
// If we have a name, use it.
|
||||||
out << "namespace " << _ident->get_local_name(scope);
|
out << "namespace " << _ident->get_local_name(scope);
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
|
if (!_attributes.is_empty()) {
|
||||||
|
out << _attributes << " ";
|
||||||
|
}
|
||||||
if (_ident != nullptr) {
|
if (_ident != nullptr) {
|
||||||
out << "namespace " << _ident->get_local_name(scope) << " {\n";
|
out << _ident->get_local_name(scope) << " {\n";
|
||||||
} else {
|
} else {
|
||||||
out << "namespace {\n";
|
out << "{\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
_scope->write(out, indent_level + 2, _scope);
|
_scope->write(out, indent_level + 2, _scope);
|
||||||
|
@ -27,7 +27,7 @@ class CPPScope;
|
|||||||
class CPPNamespace : public CPPDeclaration {
|
class CPPNamespace : public CPPDeclaration {
|
||||||
public:
|
public:
|
||||||
CPPNamespace(CPPIdentifier *ident, CPPScope *scope,
|
CPPNamespace(CPPIdentifier *ident, CPPScope *scope,
|
||||||
const CPPFile &file);
|
const CPPFile &file, CPPAttributeList attr = CPPAttributeList());
|
||||||
|
|
||||||
std::string get_simple_name() const;
|
std::string get_simple_name() const;
|
||||||
std::string get_local_name(CPPScope *scope = nullptr) const;
|
std::string get_local_name(CPPScope *scope = nullptr) const;
|
||||||
|
@ -247,6 +247,12 @@ output_instance(std::ostream &out, int indent_level, CPPScope *scope,
|
|||||||
star = ftype->_class_owner->get_fully_scoped_name() + "::*";
|
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,
|
_pointing_at->output_instance(out, indent_level, scope, complete,
|
||||||
star + prename, name);
|
star + prename, name);
|
||||||
}
|
}
|
||||||
|
@ -228,13 +228,16 @@ output_instance(std::ostream &out, int indent_level, CPPScope *scope,
|
|||||||
bool complete, const std::string &prename,
|
bool complete, const std::string &prename,
|
||||||
const std::string &name) const {
|
const std::string &name) const {
|
||||||
|
|
||||||
if (_value_category == VC_rvalue) {
|
std::string prefix((_value_category == VC_rvalue) ? "&&" : "&");
|
||||||
_pointing_at->output_instance(out, indent_level, scope, complete,
|
|
||||||
"&&" + prename, name);
|
if (!_attributes.is_empty()) {
|
||||||
} else {
|
std::ostringstream strm;
|
||||||
_pointing_at->output_instance(out, indent_level, scope, complete,
|
strm << prefix << _attributes << " ";
|
||||||
"&" + prename, name);
|
prefix = strm.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_pointing_at->output_instance(out, indent_level, scope, complete,
|
||||||
|
prefix + prename, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,8 +41,8 @@ output(std::ostream &out) const {
|
|||||||
CPPStructType::
|
CPPStructType::
|
||||||
CPPStructType(CPPStructType::Type type, CPPIdentifier *ident,
|
CPPStructType(CPPStructType::Type type, CPPIdentifier *ident,
|
||||||
CPPScope *current_scope, CPPScope *scope,
|
CPPScope *current_scope, CPPScope *scope,
|
||||||
const CPPFile &file) :
|
const CPPFile &file, CPPAttributeList attr) :
|
||||||
CPPExtensionType(type, ident, current_scope, file),
|
CPPExtensionType(type, ident, current_scope, file, std::move(attr)),
|
||||||
_scope(scope),
|
_scope(scope),
|
||||||
_final(false)
|
_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);
|
get_template_scope()->_parameters.write_formal(out, scope);
|
||||||
indent(out, indent_level);
|
indent(out, indent_level);
|
||||||
}
|
}
|
||||||
|
out << _type;
|
||||||
|
|
||||||
|
if (!_attributes.is_empty()) {
|
||||||
|
out << " " << _attributes;
|
||||||
|
}
|
||||||
|
|
||||||
if (_ident != nullptr) {
|
if (_ident != nullptr) {
|
||||||
out << _type << " " << _ident->get_local_name(scope);
|
out << " " << _ident->get_local_name(scope);
|
||||||
} else {
|
|
||||||
out << _type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_final) {
|
if (_final) {
|
||||||
|
@ -35,7 +35,8 @@ public:
|
|||||||
CPPStructType(Type type, CPPIdentifier *ident,
|
CPPStructType(Type type, CPPIdentifier *ident,
|
||||||
CPPScope *current_scope,
|
CPPScope *current_scope,
|
||||||
CPPScope *scope,
|
CPPScope *scope,
|
||||||
const CPPFile &file);
|
const CPPFile &file,
|
||||||
|
CPPAttributeList attr = CPPAttributeList());
|
||||||
CPPStructType(const CPPStructType ©);
|
CPPStructType(const CPPStructType ©);
|
||||||
void operator = (const CPPStructType ©);
|
void operator = (const CPPStructType ©);
|
||||||
|
|
||||||
|
@ -43,7 +43,8 @@ CPPTypedefType(CPPType *type, const string &name, CPPScope *current_scope) :
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
CPPTypedefType::
|
CPPTypedefType::
|
||||||
CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope) :
|
CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope,
|
||||||
|
CPPAttributeList attr) :
|
||||||
CPPType(CPPFile()),
|
CPPType(CPPFile()),
|
||||||
_type(type),
|
_type(type),
|
||||||
_ident(ident),
|
_ident(ident),
|
||||||
@ -53,6 +54,8 @@ CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope) :
|
|||||||
_ident->_native_scope = current_scope;
|
_ident->_native_scope = current_scope;
|
||||||
}
|
}
|
||||||
_subst_decl_recursive_protect = false;
|
_subst_decl_recursive_protect = false;
|
||||||
|
|
||||||
|
_attributes = std::move(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,6 +72,7 @@ CPPTypedefType(CPPType *type, CPPInstanceIdentifier *ii,
|
|||||||
assert(ii != nullptr);
|
assert(ii != nullptr);
|
||||||
_type = ii->unroll_type(type);
|
_type = ii->unroll_type(type);
|
||||||
_ident = ii->_ident;
|
_ident = ii->_ident;
|
||||||
|
_attributes = std::move(ii->_attributes);
|
||||||
ii->_ident = nullptr;
|
ii->_ident = nullptr;
|
||||||
delete ii;
|
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);
|
get_template_scope()->_parameters.write_formal(out, scope);
|
||||||
indent(out, indent_level);
|
indent(out, indent_level);
|
||||||
}
|
}
|
||||||
out << "using " << name << " = ";
|
out << "using " << name;
|
||||||
|
if (!_attributes.is_empty()) {
|
||||||
|
out << " " << _attributes;
|
||||||
|
}
|
||||||
|
out << " = ";
|
||||||
_type->output(out, 0, scope, false);
|
_type->output(out, 0, scope, false);
|
||||||
} else {
|
} else {
|
||||||
|
if (!_attributes.is_empty()) {
|
||||||
|
out << _attributes << " ";
|
||||||
|
}
|
||||||
out << "typedef ";
|
out << "typedef ";
|
||||||
_type->output_instance(out, indent_level, scope, false, "", name);
|
_type->output_instance(out, indent_level, scope, false, "", name);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,8 @@ class CPPInstanceIdentifier;
|
|||||||
class CPPTypedefType : public CPPType {
|
class CPPTypedefType : public CPPType {
|
||||||
public:
|
public:
|
||||||
CPPTypedefType(CPPType *type, const std::string &name, CPPScope *current_scope);
|
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,
|
CPPTypedefType(CPPType *type, CPPInstanceIdentifier *ii,
|
||||||
CPPScope *current_scope, const CPPFile &file);
|
CPPScope *current_scope, const CPPFile &file);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
#include "cppAttributeList.cxx"
|
||||||
#include "cppFunctionType.cxx"
|
#include "cppFunctionType.cxx"
|
||||||
#include "cppGlobals.cxx"
|
#include "cppGlobals.cxx"
|
||||||
#include "cppCommentBlock.cxx"
|
#include "cppCommentBlock.cxx"
|
||||||
|
@ -47,8 +47,4 @@ namespace std {
|
|||||||
typedef decltype(nullptr) nullptr_t;
|
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
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user