diff --git a/CppParser/include/Poco/CppParser/CppToken.h b/CppParser/include/Poco/CppParser/CppToken.h index c4e7e4566..ed57c5f2e 100644 --- a/CppParser/include/Poco/CppParser/CppToken.h +++ b/CppParser/include/Poco/CppParser/CppToken.h @@ -1,7 +1,7 @@ // // CppToken.h // -// $Id: //poco/1.4/CppParser/include/Poco/CppParser/CppToken.h#1 $ +// $Id: //poco/1.4/CppParser/include/Poco/CppParser/CppToken.h#2 $ // // Library: CppParser // Package: CppParser @@ -134,7 +134,9 @@ class CppParser_API IdentifierToken: public CppToken public: enum Keywords { - KW_AND = 1, + KW_ALIGNAS = 1, + KW_ALIGNOF, + KW_AND, KW_AND_EQ, KW_ASM, KW_AUTO, @@ -145,11 +147,15 @@ public: KW_CASE, KW_CATCH, KW_CHAR, + KW_CHAR_16T, + KW_CHAR_32T, KW_CLASS, KW_COMPL, KW_CONST, + KW_CONSTEXPR, KW_CONST_CAST, KW_CONTINUE, + KW_DECLTYPE, KW_DEFAULT, KW_DELETE, KW_DO, @@ -172,8 +178,10 @@ public: KW_MUTABLE, KW_NAMESPACE, KW_NEW, + KW_NOEXCEPT, KW_NOT, KW_NOT_EQ, + KW_NULLPTR, KW_OPERATOR, KW_OR, KW_OR_EQ, @@ -187,11 +195,13 @@ public: KW_SIGNED, KW_SIZEOF, KW_STATIC, + KW_STATIC_ASSERT, KW_STATIC_CAST, KW_STRUCT, KW_SWITCH, KW_TEMPLATE, KW_THIS, + KW_THREAD_LOCAL, KW_THROW, KW_TRUE, KW_TRY, diff --git a/CppParser/include/Poco/CppParser/Function.h b/CppParser/include/Poco/CppParser/Function.h index 2f95015ac..b390086d2 100644 --- a/CppParser/include/Poco/CppParser/Function.h +++ b/CppParser/include/Poco/CppParser/Function.h @@ -1,7 +1,7 @@ // // Function.h // -// $Id: //poco/1.4/CppParser/include/Poco/CppParser/Function.h#1 $ +// $Id: //poco/1.4/CppParser/include/Poco/CppParser/Function.h#2 $ // // Library: CppParser // Package: SymbolTable @@ -58,12 +58,17 @@ class CppParser_API Function: public Decl public: enum Flags { - FN_STATIC = 1, /// The function is static. - FN_VIRTUAL = 2, /// The function is virtual. - FN_INLINE = 4, /// The function is inline. - FN_CONST = 8, /// The function is const. - FN_TEMPLATE = 16, /// The function is a template. - FN_PURE_VIRTUAL = 32 /// The function is pure virtual. + FN_STATIC = 1, /// The function is static. + FN_VIRTUAL = 2, /// The function is virtual. + FN_INLINE = 4, /// The function is inline. + FN_CONST = 8, /// The function is const. + FN_TEMPLATE = 16, /// The function is a template. + FN_PURE_VIRTUAL = 32, /// The function is pure virtual. + FN_FINAL = 64, /// The function is final. + FN_OVERRIDE = 128, /// The function is override. + FN_NOEXCEPT = 256, /// The function is noexcept. + FN_DEFAULT = 512, /// The function is default. + FN_DELETE = 1024 /// The function has been deleted. }; typedef std::vector Parameters; @@ -94,6 +99,21 @@ public: void makePureVirtual(); /// Sets the FN_PURE_VIRTUAL flag. + + void makeFinal(); + /// Sets the FN_FINAL flag. + + void makeOverride(); + /// Sets the FN_OVERRIDE flag. + + void makeNoexcept(); + /// Sets the FN_NOEXCEPT flag. + + void makeDefault(); + /// Sets the FN_DEFAULT flag. + + void makeDelete(); + /// Sets the FN_DELETE flag. int flags() const; /// Returns the function's flags. diff --git a/CppParser/include/Poco/CppParser/Struct.h b/CppParser/include/Poco/CppParser/Struct.h index 34ea06adb..bda5c6498 100644 --- a/CppParser/include/Poco/CppParser/Struct.h +++ b/CppParser/include/Poco/CppParser/Struct.h @@ -1,7 +1,7 @@ // // Struct.h // -// $Id: //poco/1.4/CppParser/include/Poco/CppParser/Struct.h#1 $ +// $Id: //poco/1.4/CppParser/include/Poco/CppParser/Struct.h#2 $ // // Library: CppParser // Package: SymbolTable @@ -61,7 +61,8 @@ public: { FN_TEMPLATE = 1, FN_INLINE = 2, // when the whole class is inlined in a c++ file - FN_TEMPLATE_SPECIALIZATION = 4 + FN_TEMPLATE_SPECIALIZATION = 4, + FN_FINAL = 8 }; struct Base @@ -115,10 +116,16 @@ public: void makeInline(); /// Changes the class to a inline class, i.e. definition and implementation are hidden in a cpp file. + + void makeFinal(); + /// Makes the class final. bool isInline() const; /// Returns true if the complete class is inlined in a cpp file. + bool isFinal() const; + /// Returns true if the class is final. + void constructors(Functions& functions) const; /// Returns all constructors, sorted by their parameter count. @@ -190,12 +197,24 @@ inline void Struct::makeInline() } +inline void Struct::makeFinal() +{ + _flags |= FN_FINAL; +} + + inline bool Struct::isInline() const { return (_flags & FN_INLINE) != 0; } +inline bool Struct::isFinal() const +{ + return (_flags & FN_FINAL) != 0; +} + + inline bool Struct::isDerived() const { return !_bases.empty(); diff --git a/CppParser/src/CppToken.cpp b/CppParser/src/CppToken.cpp index 4ba0b053b..ee82e7ffe 100644 --- a/CppParser/src/CppToken.cpp +++ b/CppParser/src/CppToken.cpp @@ -1,7 +1,7 @@ // // CppToken.cpp // -// $Id: //poco/1.4/CppParser/src/CppToken.cpp#2 $ +// $Id: //poco/1.4/CppParser/src/CppToken.cpp#3 $ // // Library: CppParser // Package: CppParser @@ -254,6 +254,8 @@ int OperatorToken::asInteger() const IdentifierToken::IdentifierToken() { int i = 1; + _kwMap["alignas"] = i++; + _kwMap["alignof"] = i++; _kwMap["and"] = i++; _kwMap["and_eq"] = i++; _kwMap["asm"] = i++; @@ -265,11 +267,15 @@ IdentifierToken::IdentifierToken() _kwMap["case"] = i++; _kwMap["catch"] = i++; _kwMap["char"] = i++; + _kwMap["char16_t"] = i++; + _kwMap["char32_t"] = i++; _kwMap["class"] = i++; _kwMap["compl"] = i++; _kwMap["const"] = i++; + _kwMap["constexpr"] = i++; _kwMap["const_cast"] = i++; _kwMap["continue"] = i++; + _kwMap["decltype"] = i++; _kwMap["default"] = i++; _kwMap["delete"] = i++; _kwMap["do"] = i++; @@ -292,8 +298,10 @@ IdentifierToken::IdentifierToken() _kwMap["mutable"] = i++; _kwMap["namespace"] = i++; _kwMap["new"] = i++; + _kwMap["noexcept"] = i++; _kwMap["not"] = i++; _kwMap["not_eq"] = i++; + _kwMap["nullptr"] = i++; _kwMap["operator"] = i++; _kwMap["or"] = i++; _kwMap["or_eq"] = i++; @@ -307,11 +315,13 @@ IdentifierToken::IdentifierToken() _kwMap["signed"] = i++; _kwMap["sizeof"] = i++; _kwMap["static"] = i++; + _kwMap["static_assert"] = i++; _kwMap["static_cast"] = i++; _kwMap["struct"] = i++; _kwMap["switch"] = i++; _kwMap["template"] = i++; _kwMap["this"] = i++; + _kwMap["thread_local"] = i++; _kwMap["throw"] = i++; _kwMap["true"] = i++; _kwMap["try"] = i++; diff --git a/CppParser/src/Function.cpp b/CppParser/src/Function.cpp index be1976ef7..406863989 100644 --- a/CppParser/src/Function.cpp +++ b/CppParser/src/Function.cpp @@ -1,7 +1,7 @@ // // Function.cpp // -// $Id: //poco/1.4/CppParser/src/Function.cpp#1 $ +// $Id: //poco/1.4/CppParser/src/Function.cpp#2 $ // // Library: CppParser // Package: SymbolTable @@ -128,6 +128,36 @@ void Function::makePureVirtual() } +void Function::makeFinal() +{ + _flags |= FN_FINAL; +} + + +void Function::makeOverride() +{ + _flags |= FN_OVERRIDE; +} + + +void Function::makeNoexcept() +{ + _flags |= FN_NOEXCEPT; +} + + +void Function::makeDefault() +{ + _flags |= FN_DEFAULT; +} + + +void Function::makeDelete() +{ + _flags |= FN_DELETE; +} + + bool Function::isConstructor() const { return name() == nameSpace()->name(); diff --git a/CppParser/src/Parser.cpp b/CppParser/src/Parser.cpp index e4737b540..019a9ce16 100644 --- a/CppParser/src/Parser.cpp +++ b/CppParser/src/Parser.cpp @@ -1,7 +1,7 @@ // // Parser.cpp // -// $Id: //poco/1.4/CppParser/src/Parser.cpp#1 $ +// $Id: //poco/1.4/CppParser/src/Parser.cpp#2 $ // // Library: CppParser // Package: CppParser @@ -151,11 +151,13 @@ inline void Parser::append(std::string& decl, const std::string& token) } decl.append(token); if (token == "const" + || token == "constexpr" || token == "static" || token == "mutable" || token == "inline" || token == "volatile" - || token == "register") + || token == "register" + || token == "thread_local") decl.append(" "); } @@ -300,6 +302,12 @@ const Token* Parser::parseClass(const Token* pNext, std::string& decl) else syntaxError("class/struct name"); pNext = next(); + bool isFinal = false; + if (isIdentifier(pNext) && pNext->asString() == "final") + { + pNext = next(); + isFinal = true; + } if (!isOperator(pNext, OperatorToken::OP_SEMICOLON)) { // if we have a template specialization the next token will be a < @@ -320,6 +328,7 @@ const Token* Parser::parseClass(const Token* pNext, std::string& decl) if (isOperator(pNext, OperatorToken::OP_COLON) || isOperator(pNext, OperatorToken::OP_OPENBRACE)) { Struct* pClass = new Struct(decl, isClass, currentNameSpace()); + if (isFinal) pClass->makeFinal(); pushNameSpace(pClass, line); _access = access; if (isOperator(pNext, OperatorToken::OP_COLON)) @@ -632,22 +641,44 @@ const Token* Parser::parseFunc(const Token* pNext, std::string& decl) pNext = parseParameters(pNext, pFunc); expectOperator(pNext, OperatorToken::OP_CLOSPARENT, ")"); pNext = next(); - if (isKeyword(pNext, IdentifierToken::KW_CONST)) - { - if (pFunc) pFunc->makeConst(); - pNext = next(); - } - if (isKeyword(pNext, IdentifierToken::KW_THROW)) - { - while (!isOperator(pNext, OperatorToken::OP_ASSIGN) && !isOperator(pNext, OperatorToken::OP_SEMICOLON) && - !isOperator(pNext, OperatorToken::OP_OPENBRACE) && !isEOF(pNext)) + while (pNext->is(Poco::Token::IDENTIFIER_TOKEN) || pNext->is(Poco::Token::KEYWORD_TOKEN)) + { + if (isKeyword(pNext, IdentifierToken::KW_CONST)) + { + if (pFunc) pFunc->makeConst(); pNext = next(); + } + if (isKeyword(pNext, IdentifierToken::KW_THROW)) + { + while (!isOperator(pNext, OperatorToken::OP_ASSIGN) && !isOperator(pNext, OperatorToken::OP_SEMICOLON) && + !isOperator(pNext, OperatorToken::OP_OPENBRACE) && !isEOF(pNext)) + pNext = next(); + } + else if (isKeyword(pNext, IdentifierToken::KW_NOEXCEPT)) + { + if (pFunc) pFunc->makeNoexcept(); + pNext = next(); + } + else if (isIdentifier(pNext) && pNext->asString() == "override") + { + if (pFunc) pFunc->makeOverride(); + pNext = next(); + } + else if (isIdentifier(pNext) && pNext->asString() == "final") + { + if (pFunc) pFunc->makeFinal(); + pNext = next(); + } } if (isOperator(pNext, OperatorToken::OP_ASSIGN)) { pNext = next(); - if (!pNext->is(Token::INTEGER_LITERAL_TOKEN)) - syntaxError("0"); + if (!pNext->is(Token::INTEGER_LITERAL_TOKEN) && !isKeyword(pNext, IdentifierToken::KW_DEFAULT) && !isKeyword(pNext, IdentifierToken::KW_DELETE)) + syntaxError("0, default or delete"); + if (isKeyword(pNext, IdentifierToken::KW_DEFAULT)) + pFunc->makeDefault(); + else if (isKeyword(pNext, IdentifierToken::KW_DELETE)) + pFunc->makeDelete(); pNext = next(); if (pFunc) pFunc->makePureVirtual(); expectOperator(pNext, OperatorToken::OP_SEMICOLON, ";");