diff --git a/CppParser/include/Poco/CppParser/Attributes.h b/CppParser/include/Poco/CppParser/Attributes.h index 3c1519b2d..e127ad55b 100644 --- a/CppParser/include/Poco/CppParser/Attributes.h +++ b/CppParser/include/Poco/CppParser/Attributes.h @@ -32,8 +32,8 @@ class CppParser_API Attributes /// name and values are strings. { public: - typedef std::map AttrMap; - typedef AttrMap::const_iterator Iterator; + using AttrMap = std::map; + using Iterator = AttrMap::const_iterator; Attributes(); /// Creates the Attributes object. diff --git a/CppParser/include/Poco/CppParser/CppToken.h b/CppParser/include/Poco/CppParser/CppToken.h index 0aef06298..5338d4c8c 100644 --- a/CppParser/include/Poco/CppParser/CppToken.h +++ b/CppParser/include/Poco/CppParser/CppToken.h @@ -46,6 +46,8 @@ public: { OP_OPENBRACKET = 1, // [ OP_CLOSBRACKET, // ] + OP_DBL_OPENBRACKET, // [[ + OP_DBL_CLOSBRACKET, // ]] OP_OPENPARENT, // ( OP_CLOSPARENT, // ) OP_OPENBRACE, // { @@ -101,7 +103,7 @@ public: int asInteger() const; private: - typedef std::map OpMap; + using OpMap = std::map; OpMap _opMap; }; @@ -112,7 +114,7 @@ class CppParser_API IdentifierToken: public CppToken public: enum Keywords { - KW_ALIGNAS = 1, + KW_ALIGNAS = 100, // Note: start with 100 to avoid overlapping definitions with operators KW_ALIGNOF, KW_AND, KW_AND_EQ, @@ -206,7 +208,7 @@ public: int asInteger() const; private: - typedef std::map KWMap; + using KWMap = std::map; KWMap _kwMap; }; diff --git a/CppParser/include/Poco/CppParser/Decl.h b/CppParser/include/Poco/CppParser/Decl.h index c67e3069f..d8b89d1ea 100644 --- a/CppParser/include/Poco/CppParser/Decl.h +++ b/CppParser/include/Poco/CppParser/Decl.h @@ -28,7 +28,7 @@ namespace CppParser { class CppParser_API Decl: public Symbol /// This class represents a simple declaration in a C++ source file. - /// It is a base class for Function, TypeDef or Variable. + /// It is a base class for Function, TypeDef, Using or Variable. { public: Decl(const std::string& decl, NameSpace* pNameSpace); diff --git a/CppParser/include/Poco/CppParser/Enum.h b/CppParser/include/Poco/CppParser/Enum.h index 6063d4c02..046a2117e 100644 --- a/CppParser/include/Poco/CppParser/Enum.h +++ b/CppParser/include/Poco/CppParser/Enum.h @@ -37,8 +37,8 @@ class CppParser_API Enum: public Symbol /// a collection of EnumValues. { public: - typedef std::vector Values; - typedef Values::const_iterator Iterator; + using Values = std::vector; + using Iterator = Values::const_iterator; enum Flags { diff --git a/CppParser/include/Poco/CppParser/Function.h b/CppParser/include/Poco/CppParser/Function.h index e060f61ee..b26e26e90 100644 --- a/CppParser/include/Poco/CppParser/Function.h +++ b/CppParser/include/Poco/CppParser/Function.h @@ -49,8 +49,8 @@ public: FN_DELETE = 1024 /// The function has been deleted. }; - typedef std::vector Parameters; - typedef Parameters::const_iterator Iterator; + using Parameters = std::vector; + using Iterator = Parameters::const_iterator; Function(const std::string& decl, NameSpace* pNameSpace); /// Creates the Function. diff --git a/CppParser/include/Poco/CppParser/NameSpace.h b/CppParser/include/Poco/CppParser/NameSpace.h index 9f5b3dab5..f3c0c56b9 100644 --- a/CppParser/include/Poco/CppParser/NameSpace.h +++ b/CppParser/include/Poco/CppParser/NameSpace.h @@ -33,10 +33,10 @@ class CppParser_API NameSpace: public Symbol /// This class represents a namespace. { public: - typedef std::multimap SymbolTable; - typedef SymbolTable::const_iterator Iterator; - typedef std::map AliasMap; - typedef std::vector NameSpaceVec; + using SymbolTable = std::multimap; + using Iterator = SymbolTable::const_iterator; + using AliasMap = std::map; + using NameSpaceVec = std::vector; NameSpace(); /// Creates the NameSpace. diff --git a/CppParser/include/Poco/CppParser/Parser.h b/CppParser/include/Poco/CppParser/Parser.h index 060551b8c..098cbc6da 100644 --- a/CppParser/include/Poco/CppParser/Parser.h +++ b/CppParser/include/Poco/CppParser/Parser.h @@ -73,7 +73,7 @@ protected: const Poco::Token* parseExtern(const Poco::Token* pNext); const Poco::Token* parseTypeDef(const Poco::Token* pNext); const Poco::Token* parseUsing(const Poco::Token* pNext); - const Poco::Token* parseFunc(const Poco::Token* pNext, std::string& decl); + const Poco::Token* parseFunc(const Poco::Token* pNext, const std::string& attrs, std::string& decl); const Poco::Token* parseParameters(const Poco::Token* pNext, Function* pFunc); const Poco::Token* parseBlock(const Poco::Token* pNext); const Poco::Token* parseEnum(const Poco::Token* pNext); @@ -82,6 +82,7 @@ protected: const Poco::Token* parseClassMembers(const Poco::Token* pNext, Struct* pClass); const Poco::Token* parseAccess(const Poco::Token* pNext); const Poco::Token* parseIdentifier(const Poco::Token* pNext, std::string& id); + const Poco::Token* parseAttributes(const Poco::Token* pNext, std::string& attrs); void addSymbol(Symbol* pSymbol, int lineNumber, bool addGST = true); void pushNameSpace(NameSpace* pNameSpace, int lineNumber, bool addGST = true); @@ -102,7 +103,7 @@ protected: const Poco::Token* nextToken(); private: - typedef std::vector NSStack; + using NSStack = std::vector; NameSpace::SymbolTable& _gst; Poco::CountingInputStream _istr; diff --git a/CppParser/include/Poco/CppParser/Struct.h b/CppParser/include/Poco/CppParser/Struct.h index 2a5a17019..6983cab40 100644 --- a/CppParser/include/Poco/CppParser/Struct.h +++ b/CppParser/include/Poco/CppParser/Struct.h @@ -51,13 +51,13 @@ public: Struct* pClass; }; - typedef std::vector BaseClasses; - typedef BaseClasses::const_iterator BaseIterator; - typedef std::vector StructVec; - typedef StructVec::const_iterator DerivedIterator; - typedef std::vector Functions; - typedef std::set FunctionSet; - typedef std::set StructSet; + using BaseClasses = std::vector; + using BaseIterator = BaseClasses::const_iterator; + using StructVec = std::vector; + using DerivedIterator = StructVec::const_iterator; + using Functions = std::vector; + using FunctionSet = std::set; + using StructSet = std::set; Struct(const std::string& decl, bool isClass, NameSpace* pNameSpace); /// Creates the Struct. diff --git a/CppParser/include/Poco/CppParser/Symbol.h b/CppParser/include/Poco/CppParser/Symbol.h index 8bae391f3..035eef647 100644 --- a/CppParser/include/Poco/CppParser/Symbol.h +++ b/CppParser/include/Poco/CppParser/Symbol.h @@ -85,6 +85,13 @@ public: Access getAccess() const; /// Returns the symbol's access. + void setAttributeList(const std::string& attrs); + /// Sets the C++11 attribute list, e.g. "[[noreturn]]". + + const std::string& getAttributeList() const; + /// Returns the C++11 attribute list, or an empty string + /// if the symbol does not have one. + void setDocumentation(const std::string& text); /// Sets the symbol's documentation. @@ -169,6 +176,7 @@ private: std::string _package; std::string _library; Attributes _attrs; + std::string _attributeList; static int _nextId; }; @@ -189,6 +197,12 @@ inline const std::string& Symbol::name() const } +inline const std::string& Symbol::getAttributeList() const +{ + return _attributeList; +} + + inline const std::string& Symbol::getDocumentation() const { return _documentation; diff --git a/CppParser/src/CppToken.cpp b/CppParser/src/CppToken.cpp index 9cd9e98b2..7bb6c7b89 100644 --- a/CppParser/src/CppToken.cpp +++ b/CppParser/src/CppToken.cpp @@ -49,9 +49,11 @@ void CppToken::syntaxError(const std::string& expected, const std::string& actua OperatorToken::OperatorToken() { - int i = 1; + int i = OP_OPENBRACKET; _opMap["["] = i++; _opMap["]"] = i++; + _opMap["[["] = i++; + _opMap["]]"] = i++; _opMap["("] = i++; _opMap[")"] = i++; _opMap["{"] = i++; @@ -159,13 +161,23 @@ void OperatorToken::finish(std::istream& istr) case ')': case '{': case '}': - case '[': - case ']': case ';': case '?': case '~': case ',': break; + case '[': + if (next == '[') + { + _value += (char) istr.get(); + } + break; + case ']': + if (next == ']') + { + _value += (char) istr.get(); + } + break; case '.': if (next == '.') { @@ -231,7 +243,7 @@ int OperatorToken::asInteger() const IdentifierToken::IdentifierToken() { - int i = 1; + int i = KW_ALIGNAS; _kwMap["alignas"] = i++; _kwMap["alignof"] = i++; _kwMap["and"] = i++; diff --git a/CppParser/src/Parser.cpp b/CppParser/src/Parser.cpp index 1da09fabd..61cc3e82b 100644 --- a/CppParser/src/Parser.cpp +++ b/CppParser/src/Parser.cpp @@ -39,6 +39,7 @@ using Poco::NumberFormatter; using Poco::SyntaxException; using Poco::icompare; using Poco::trimInPlace; +using namespace std::string_literals; namespace Poco { @@ -117,6 +118,8 @@ inline void Parser::append(std::string& decl, const std::string& token) token != "," && token != "[" && token != "]" && + token != "[[" && + token != "]]" && last != '~' && last != ':' && last != '(' && @@ -380,7 +383,7 @@ const Token* Parser::parseClassMembers(const Token* pNext, Struct* /*pClass*/) poco_assert (isOperator(pNext, OperatorToken::OP_OPENBRACE)); pNext = next(); - while (pNext->is(Token::IDENTIFIER_TOKEN) || pNext->is(Token::KEYWORD_TOKEN) || isOperator(pNext, OperatorToken::OP_COMPL) || isOperator(pNext, OperatorToken::OP_DBL_COLON)) + while (pNext->is(Token::IDENTIFIER_TOKEN) || pNext->is(Token::KEYWORD_TOKEN) || isOperator(pNext, OperatorToken::OP_COMPL) || isOperator(pNext, OperatorToken::OP_DBL_COLON) || isOperator(pNext, OperatorToken::OP_DBL_OPENBRACKET)) { switch (pNext->asInteger()) { @@ -575,6 +578,11 @@ const Token* Parser::parseVarFunc(const Token* pNext) const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl) { _pCurrentSymbol = 0; + std::string attrs; + if (isOperator(pNext, OperatorToken::OP_DBL_OPENBRACKET)) + { + pNext = parseAttributes(pNext, attrs); + } if (isKeyword(pNext, IdentifierToken::KW_EXTERN)) { pNext = parseExtern(pNext); @@ -596,6 +604,7 @@ const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl) if (!currentNameSpace()->lookup(name)) { Variable* pVar = new Variable(decl, currentNameSpace()); + pVar->setAttributeList(attrs); addSymbol(pVar, static_cast(_istr.getCurrentLineNumber())); } pNext = next(); @@ -611,7 +620,7 @@ const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl) pNext = next(); expectOperator(pNext, OperatorToken::OP_OPENPARENT, "("); } - pNext = parseFunc(pNext, decl); + pNext = parseFunc(pNext, attrs, decl); } } _pCurrentSymbol = 0; @@ -641,7 +650,7 @@ const Token* Parser::parseExtern(const Token* pNext) } -const Token* Parser::parseFunc(const Token* pNext, std::string& decl) +const Token* Parser::parseFunc(const Token* pNext, const std::string& attrs, std::string& decl) { poco_assert (isOperator(pNext, OperatorToken::OP_OPENPARENT)); @@ -651,6 +660,7 @@ const Token* Parser::parseFunc(const Token* pNext, std::string& decl) if (name.find(':') == std::string::npos) { pFunc = new Function(decl, currentNameSpace()); + pFunc->setAttributeList(attrs); addSymbol(pFunc, line); } pNext = parseParameters(pNext, pFunc); @@ -909,6 +919,25 @@ const Token* Parser::parseIdentifier(const Token* pNext, std::string& id) } +const Poco::Token* Parser::parseAttributes(const Poco::Token* pNext, std::string& attrs) +{ + poco_assert (isOperator(pNext, OperatorToken::OP_DBL_OPENBRACKET)); + append(attrs, pNext); + pNext = next(); + while (pNext && !isOperator(pNext, OperatorToken::OP_DBL_CLOSBRACKET)) + { + append(attrs, pNext); + pNext = next(); + } + if (pNext) + { + append(attrs, pNext); + pNext = next(); + } + return pNext; +} + + void Parser::addSymbol(Symbol* pSymbol, int lineNumber, bool addGST) { pSymbol->setLineNumber(lineNumber); diff --git a/CppParser/src/Symbol.cpp b/CppParser/src/Symbol.cpp index 3a9ecf326..50c436b14 100644 --- a/CppParser/src/Symbol.cpp +++ b/CppParser/src/Symbol.cpp @@ -59,6 +59,12 @@ void Symbol::setAccess(Access access) } +void Symbol::setAttributeList(const std::string& attrs) +{ + _attributeList = attrs; +} + + void Symbol::setDocumentation(const std::string& text) { _documentation = text;