11//
22// Parser.cpp
33//
4- // $Id: //poco/1.4/CppParser/src/Parser.cpp#1 $
4+ // $Id: //poco/1.4/CppParser/src/Parser.cpp#2 $
55//
66// Library: CppParser
77// Package: CppParser
@@ -151,11 +151,13 @@ inline void Parser::append(std::string& decl, const std::string& token)
151151 }
152152 decl.append (token);
153153 if (token == " const"
154+ || token == " constexpr"
154155 || token == " static"
155156 || token == " mutable"
156157 || token == " inline"
157158 || token == " volatile"
158- || token == " register" )
159+ || token == " register"
160+ || token == " thread_local" )
159161 decl.append (" " );
160162}
161163
@@ -300,6 +302,12 @@ const Token* Parser::parseClass(const Token* pNext, std::string& decl)
300302 else
301303 syntaxError (" class/struct name" );
302304 pNext = next ();
305+ bool isFinal = false ;
306+ if (isIdentifier (pNext) && pNext->asString () == " final" )
307+ {
308+ pNext = next ();
309+ isFinal = true ;
310+ }
303311 if (!isOperator (pNext, OperatorToken::OP_SEMICOLON ))
304312 {
305313 // 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)
320328 if (isOperator (pNext, OperatorToken::OP_COLON ) || isOperator (pNext, OperatorToken::OP_OPENBRACE ))
321329 {
322330 Struct* pClass = new Struct (decl, isClass, currentNameSpace ());
331+ if (isFinal) pClass->makeFinal ();
323332 pushNameSpace (pClass, line);
324333 _access = access;
325334 if (isOperator (pNext, OperatorToken::OP_COLON ))
@@ -632,22 +641,44 @@ const Token* Parser::parseFunc(const Token* pNext, std::string& decl)
632641 pNext = parseParameters (pNext, pFunc);
633642 expectOperator (pNext, OperatorToken::OP_CLOSPARENT , " )" );
634643 pNext = next ();
635- if (isKeyword (pNext, IdentifierToken::KW_CONST ))
636- {
637- if (pFunc) pFunc->makeConst ();
638- pNext = next ();
639- }
640- if (isKeyword (pNext, IdentifierToken::KW_THROW ))
641- {
642- while (!isOperator (pNext, OperatorToken::OP_ASSIGN ) && !isOperator (pNext, OperatorToken::OP_SEMICOLON ) &&
643- !isOperator (pNext, OperatorToken::OP_OPENBRACE ) && !isEOF (pNext))
644+ while (pNext->is (Poco::Token::IDENTIFIER_TOKEN ) || pNext->is (Poco::Token::KEYWORD_TOKEN ))
645+ {
646+ if (isKeyword (pNext, IdentifierToken::KW_CONST ))
647+ {
648+ if (pFunc) pFunc->makeConst ();
644649 pNext = next ();
650+ }
651+ if (isKeyword (pNext, IdentifierToken::KW_THROW ))
652+ {
653+ while (!isOperator (pNext, OperatorToken::OP_ASSIGN ) && !isOperator (pNext, OperatorToken::OP_SEMICOLON ) &&
654+ !isOperator (pNext, OperatorToken::OP_OPENBRACE ) && !isEOF (pNext))
655+ pNext = next ();
656+ }
657+ else if (isKeyword (pNext, IdentifierToken::KW_NOEXCEPT ))
658+ {
659+ if (pFunc) pFunc->makeNoexcept ();
660+ pNext = next ();
661+ }
662+ else if (isIdentifier (pNext) && pNext->asString () == " override" )
663+ {
664+ if (pFunc) pFunc->makeOverride ();
665+ pNext = next ();
666+ }
667+ else if (isIdentifier (pNext) && pNext->asString () == " final" )
668+ {
669+ if (pFunc) pFunc->makeFinal ();
670+ pNext = next ();
671+ }
645672 }
646673 if (isOperator (pNext, OperatorToken::OP_ASSIGN ))
647674 {
648675 pNext = next ();
649- if (!pNext->is (Token::INTEGER_LITERAL_TOKEN ))
650- syntaxError (" 0" );
676+ if (!pNext->is (Token::INTEGER_LITERAL_TOKEN ) && !isKeyword (pNext, IdentifierToken::KW_DEFAULT ) && !isKeyword (pNext, IdentifierToken::KW_DELETE ))
677+ syntaxError (" 0, default or delete" );
678+ if (isKeyword (pNext, IdentifierToken::KW_DEFAULT ))
679+ pFunc->makeDefault ();
680+ else if (isKeyword (pNext, IdentifierToken::KW_DELETE ))
681+ pFunc->makeDelete ();
651682 pNext = next ();
652683 if (pFunc) pFunc->makePureVirtual ();
653684 expectOperator (pNext, OperatorToken::OP_SEMICOLON , " ;" );
0 commit comments