added support for new C++11 keywords and features to CppParser and PocoDoc

This commit is contained in:
Guenter Obiltschnig 2012-11-17 10:06:20 +01:00
parent 83fd9e4a29
commit a6dd7894da
6 changed files with 146 additions and 26 deletions

View File

@ -1,7 +1,7 @@
// //
// CppToken.h // 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 // Library: CppParser
// Package: CppParser // Package: CppParser
@ -134,7 +134,9 @@ class CppParser_API IdentifierToken: public CppToken
public: public:
enum Keywords enum Keywords
{ {
KW_AND = 1, KW_ALIGNAS = 1,
KW_ALIGNOF,
KW_AND,
KW_AND_EQ, KW_AND_EQ,
KW_ASM, KW_ASM,
KW_AUTO, KW_AUTO,
@ -145,11 +147,15 @@ public:
KW_CASE, KW_CASE,
KW_CATCH, KW_CATCH,
KW_CHAR, KW_CHAR,
KW_CHAR_16T,
KW_CHAR_32T,
KW_CLASS, KW_CLASS,
KW_COMPL, KW_COMPL,
KW_CONST, KW_CONST,
KW_CONSTEXPR,
KW_CONST_CAST, KW_CONST_CAST,
KW_CONTINUE, KW_CONTINUE,
KW_DECLTYPE,
KW_DEFAULT, KW_DEFAULT,
KW_DELETE, KW_DELETE,
KW_DO, KW_DO,
@ -172,8 +178,10 @@ public:
KW_MUTABLE, KW_MUTABLE,
KW_NAMESPACE, KW_NAMESPACE,
KW_NEW, KW_NEW,
KW_NOEXCEPT,
KW_NOT, KW_NOT,
KW_NOT_EQ, KW_NOT_EQ,
KW_NULLPTR,
KW_OPERATOR, KW_OPERATOR,
KW_OR, KW_OR,
KW_OR_EQ, KW_OR_EQ,
@ -187,11 +195,13 @@ public:
KW_SIGNED, KW_SIGNED,
KW_SIZEOF, KW_SIZEOF,
KW_STATIC, KW_STATIC,
KW_STATIC_ASSERT,
KW_STATIC_CAST, KW_STATIC_CAST,
KW_STRUCT, KW_STRUCT,
KW_SWITCH, KW_SWITCH,
KW_TEMPLATE, KW_TEMPLATE,
KW_THIS, KW_THIS,
KW_THREAD_LOCAL,
KW_THROW, KW_THROW,
KW_TRUE, KW_TRUE,
KW_TRY, KW_TRY,

View File

@ -1,7 +1,7 @@
// //
// Function.h // 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 // Library: CppParser
// Package: SymbolTable // Package: SymbolTable
@ -58,12 +58,17 @@ class CppParser_API Function: public Decl
public: public:
enum Flags enum Flags
{ {
FN_STATIC = 1, /// The function is static. FN_STATIC = 1, /// The function is static.
FN_VIRTUAL = 2, /// The function is virtual. FN_VIRTUAL = 2, /// The function is virtual.
FN_INLINE = 4, /// The function is inline. FN_INLINE = 4, /// The function is inline.
FN_CONST = 8, /// The function is const. FN_CONST = 8, /// The function is const.
FN_TEMPLATE = 16, /// The function is a template. FN_TEMPLATE = 16, /// The function is a template.
FN_PURE_VIRTUAL = 32 /// The function is pure virtual. 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<Parameter*> Parameters; typedef std::vector<Parameter*> Parameters;
@ -94,6 +99,21 @@ public:
void makePureVirtual(); void makePureVirtual();
/// Sets the FN_PURE_VIRTUAL flag. /// 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; int flags() const;
/// Returns the function's flags. /// Returns the function's flags.

View File

@ -1,7 +1,7 @@
// //
// Struct.h // 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 // Library: CppParser
// Package: SymbolTable // Package: SymbolTable
@ -61,7 +61,8 @@ public:
{ {
FN_TEMPLATE = 1, FN_TEMPLATE = 1,
FN_INLINE = 2, // when the whole class is inlined in a c++ file 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 struct Base
@ -115,10 +116,16 @@ public:
void makeInline(); void makeInline();
/// Changes the class to a inline class, i.e. definition and implementation are hidden in a cpp file. /// 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; bool isInline() const;
/// Returns true if the complete class is inlined in a cpp file. /// 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; void constructors(Functions& functions) const;
/// Returns all constructors, sorted by their parameter count. /// 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 inline bool Struct::isInline() const
{ {
return (_flags & FN_INLINE) != 0; return (_flags & FN_INLINE) != 0;
} }
inline bool Struct::isFinal() const
{
return (_flags & FN_FINAL) != 0;
}
inline bool Struct::isDerived() const inline bool Struct::isDerived() const
{ {
return !_bases.empty(); return !_bases.empty();

View File

@ -1,7 +1,7 @@
// //
// CppToken.cpp // CppToken.cpp
// //
// $Id: //poco/1.4/CppParser/src/CppToken.cpp#2 $ // $Id: //poco/1.4/CppParser/src/CppToken.cpp#3 $
// //
// Library: CppParser // Library: CppParser
// Package: CppParser // Package: CppParser
@ -254,6 +254,8 @@ int OperatorToken::asInteger() const
IdentifierToken::IdentifierToken() IdentifierToken::IdentifierToken()
{ {
int i = 1; int i = 1;
_kwMap["alignas"] = i++;
_kwMap["alignof"] = i++;
_kwMap["and"] = i++; _kwMap["and"] = i++;
_kwMap["and_eq"] = i++; _kwMap["and_eq"] = i++;
_kwMap["asm"] = i++; _kwMap["asm"] = i++;
@ -265,11 +267,15 @@ IdentifierToken::IdentifierToken()
_kwMap["case"] = i++; _kwMap["case"] = i++;
_kwMap["catch"] = i++; _kwMap["catch"] = i++;
_kwMap["char"] = i++; _kwMap["char"] = i++;
_kwMap["char16_t"] = i++;
_kwMap["char32_t"] = i++;
_kwMap["class"] = i++; _kwMap["class"] = i++;
_kwMap["compl"] = i++; _kwMap["compl"] = i++;
_kwMap["const"] = i++; _kwMap["const"] = i++;
_kwMap["constexpr"] = i++;
_kwMap["const_cast"] = i++; _kwMap["const_cast"] = i++;
_kwMap["continue"] = i++; _kwMap["continue"] = i++;
_kwMap["decltype"] = i++;
_kwMap["default"] = i++; _kwMap["default"] = i++;
_kwMap["delete"] = i++; _kwMap["delete"] = i++;
_kwMap["do"] = i++; _kwMap["do"] = i++;
@ -292,8 +298,10 @@ IdentifierToken::IdentifierToken()
_kwMap["mutable"] = i++; _kwMap["mutable"] = i++;
_kwMap["namespace"] = i++; _kwMap["namespace"] = i++;
_kwMap["new"] = i++; _kwMap["new"] = i++;
_kwMap["noexcept"] = i++;
_kwMap["not"] = i++; _kwMap["not"] = i++;
_kwMap["not_eq"] = i++; _kwMap["not_eq"] = i++;
_kwMap["nullptr"] = i++;
_kwMap["operator"] = i++; _kwMap["operator"] = i++;
_kwMap["or"] = i++; _kwMap["or"] = i++;
_kwMap["or_eq"] = i++; _kwMap["or_eq"] = i++;
@ -307,11 +315,13 @@ IdentifierToken::IdentifierToken()
_kwMap["signed"] = i++; _kwMap["signed"] = i++;
_kwMap["sizeof"] = i++; _kwMap["sizeof"] = i++;
_kwMap["static"] = i++; _kwMap["static"] = i++;
_kwMap["static_assert"] = i++;
_kwMap["static_cast"] = i++; _kwMap["static_cast"] = i++;
_kwMap["struct"] = i++; _kwMap["struct"] = i++;
_kwMap["switch"] = i++; _kwMap["switch"] = i++;
_kwMap["template"] = i++; _kwMap["template"] = i++;
_kwMap["this"] = i++; _kwMap["this"] = i++;
_kwMap["thread_local"] = i++;
_kwMap["throw"] = i++; _kwMap["throw"] = i++;
_kwMap["true"] = i++; _kwMap["true"] = i++;
_kwMap["try"] = i++; _kwMap["try"] = i++;

View File

@ -1,7 +1,7 @@
// //
// Function.cpp // Function.cpp
// //
// $Id: //poco/1.4/CppParser/src/Function.cpp#1 $ // $Id: //poco/1.4/CppParser/src/Function.cpp#2 $
// //
// Library: CppParser // Library: CppParser
// Package: SymbolTable // 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 bool Function::isConstructor() const
{ {
return name() == nameSpace()->name(); return name() == nameSpace()->name();

View File

@ -1,7 +1,7 @@
// //
// Parser.cpp // Parser.cpp
// //
// $Id: //poco/1.4/CppParser/src/Parser.cpp#1 $ // $Id: //poco/1.4/CppParser/src/Parser.cpp#2 $
// //
// Library: CppParser // Library: CppParser
// Package: CppParser // Package: CppParser
@ -151,11 +151,13 @@ inline void Parser::append(std::string& decl, const std::string& token)
} }
decl.append(token); decl.append(token);
if (token == "const" if (token == "const"
|| token == "constexpr"
|| token == "static" || token == "static"
|| token == "mutable" || token == "mutable"
|| token == "inline" || token == "inline"
|| token == "volatile" || token == "volatile"
|| token == "register") || token == "register"
|| token == "thread_local")
decl.append(" "); decl.append(" ");
} }
@ -300,6 +302,12 @@ const Token* Parser::parseClass(const Token* pNext, std::string& decl)
else else
syntaxError("class/struct name"); syntaxError("class/struct name");
pNext = next(); pNext = next();
bool isFinal = false;
if (isIdentifier(pNext) && pNext->asString() == "final")
{
pNext = next();
isFinal = true;
}
if (!isOperator(pNext, OperatorToken::OP_SEMICOLON)) if (!isOperator(pNext, OperatorToken::OP_SEMICOLON))
{ {
// if we have a template specialization the next token will be a < // 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)) if (isOperator(pNext, OperatorToken::OP_COLON) || isOperator(pNext, OperatorToken::OP_OPENBRACE))
{ {
Struct* pClass = new Struct(decl, isClass, currentNameSpace()); Struct* pClass = new Struct(decl, isClass, currentNameSpace());
if (isFinal) pClass->makeFinal();
pushNameSpace(pClass, line); pushNameSpace(pClass, line);
_access = access; _access = access;
if (isOperator(pNext, OperatorToken::OP_COLON)) if (isOperator(pNext, OperatorToken::OP_COLON))
@ -632,22 +641,44 @@ const Token* Parser::parseFunc(const Token* pNext, std::string& decl)
pNext = parseParameters(pNext, pFunc); pNext = parseParameters(pNext, pFunc);
expectOperator(pNext, OperatorToken::OP_CLOSPARENT, ")"); expectOperator(pNext, OperatorToken::OP_CLOSPARENT, ")");
pNext = next(); pNext = next();
if (isKeyword(pNext, IdentifierToken::KW_CONST)) while (pNext->is(Poco::Token::IDENTIFIER_TOKEN) || pNext->is(Poco::Token::KEYWORD_TOKEN))
{ {
if (pFunc) pFunc->makeConst(); if (isKeyword(pNext, IdentifierToken::KW_CONST))
pNext = next(); {
} if (pFunc) pFunc->makeConst();
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(); 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)) if (isOperator(pNext, OperatorToken::OP_ASSIGN))
{ {
pNext = next(); pNext = next();
if (!pNext->is(Token::INTEGER_LITERAL_TOKEN)) if (!pNext->is(Token::INTEGER_LITERAL_TOKEN) && !isKeyword(pNext, IdentifierToken::KW_DEFAULT) && !isKeyword(pNext, IdentifierToken::KW_DELETE))
syntaxError("0"); syntaxError("0, default or delete");
if (isKeyword(pNext, IdentifierToken::KW_DEFAULT))
pFunc->makeDefault();
else if (isKeyword(pNext, IdentifierToken::KW_DELETE))
pFunc->makeDelete();
pNext = next(); pNext = next();
if (pFunc) pFunc->makePureVirtual(); if (pFunc) pFunc->makePureVirtual();
expectOperator(pNext, OperatorToken::OP_SEMICOLON, ";"); expectOperator(pNext, OperatorToken::OP_SEMICOLON, ";");