Commit fcf67d7d authored by Erik Verbruggen's avatar Erik Verbruggen

Added clone methods to the AST.

parent 4bb0e85c
......@@ -77,3 +77,4 @@ tests/auto/qml/qmldesigner/bauhaustests/tst_bauhaus
tests/auto/qml/qmldesigner/coretests/tst_qmldesigner_core
tests/auto/qml/qmldesigner/propertyeditortests/tst_propertyeditor
tests/auto/profilewriter/tst_profilewriter
src/tools/cplusplus/generate-ast
......@@ -2030,8 +2030,8 @@ unsigned ObjCTypeNameAST::lastToken() const
if (type_id)
return type_id->lastToken();
if (type_qualifier)
return type_qualifier + 1;
if (type_qualifier_token)
return type_qualifier_token + 1;
return lparen_token + 1;
}
......@@ -2214,22 +2214,22 @@ unsigned ObjCMethodDeclarationAST::lastToken() const
unsigned ObjCSynthesizedPropertyAST::firstToken() const
{
if (property_identifier)
return property_identifier;
if (property_identifier_token)
return property_identifier_token;
else if (equals_token)
return equals_token;
else
return property_alias_identifier;
return alias_identifier_token;
}
unsigned ObjCSynthesizedPropertyAST::lastToken() const
{
if (property_alias_identifier)
return property_alias_identifier + 1;
if (alias_identifier_token)
return alias_identifier_token + 1;
else if (equals_token)
return equals_token + 1;
else
return property_identifier + 1;
return property_identifier_token + 1;
}
unsigned ObjCSynthesizedPropertiesDeclarationAST::firstToken() const
......
This diff is collapsed.
This diff is collapsed.
......@@ -4753,12 +4753,12 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST;
ast->property_identifier_list = last;
last->value = new (_pool) ObjCSynthesizedPropertyAST;
match(T_IDENTIFIER, &(last->value->property_identifier));
match(T_IDENTIFIER, &(last->value->property_identifier_token));
if (LA() == T_EQUAL) {
last->value->equals_token = consumeToken();
match(T_IDENTIFIER, &(last->value->property_alias_identifier));
match(T_IDENTIFIER, &(last->value->alias_identifier_token));
}
while (LA() == T_COMMA) {
......@@ -4768,12 +4768,12 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
last = last->next;
last->value = new (_pool) ObjCSynthesizedPropertyAST;
match(T_IDENTIFIER, &(last->value->property_identifier));
match(T_IDENTIFIER, &(last->value->property_identifier_token));
if (LA() == T_EQUAL) {
last->value->equals_token = consumeToken();
match(T_IDENTIFIER, &(last->value->property_alias_identifier));
match(T_IDENTIFIER, &(last->value->alias_identifier_token));
}
}
......@@ -5179,7 +5179,7 @@ bool Parser::parseObjCTypeName(ObjCTypeNameAST *&node)
ObjCTypeNameAST *ast = new (_pool) ObjCTypeNameAST;
match(T_LPAREN, &(ast->lparen_token));
parseObjCTypeQualifiers(ast->type_qualifier);
parseObjCTypeQualifiers(ast->type_qualifier_token);
parseTypeId(ast->type_id);
match(T_RPAREN, &(ast->rparen_token));
node = ast;
......
......@@ -46,6 +46,7 @@ SOURCES += \
$$PWD/ASTVisit.cpp \
$$PWD/ASTMatch0.cpp \
$$PWD/ASTVisitor.cpp \
$$PWD/ASTClone.cpp \
$$PWD/ASTPatternBuilder.cpp \
$$PWD/ASTMatcher.cpp \
$$PWD/TypeMatcher.cpp \
......
......@@ -5,11 +5,11 @@
QT = core gui
macx:CONFIG -= app_bundle
TEMPLATE = app
TARGET =
TARGET = generate-ast
DEPENDPATH += .
INCLUDEPATH += .
include(../../libs/cplusplus/cplusplus-lib.pri)
# Input
SOURCES += Main.cpp
SOURCES += generate-ast.cpp
......@@ -83,6 +83,18 @@ static const char copyrightHeader[] =
"**************************************************************************/\n"
;
static const char generatedHeader[] =
"\n"
"//\n"
"// W A R N I N G\n"
"// -------------\n"
"//\n"
"// This file is automatically generated.\n"
"// Changes will be lost.\n"
"//\n"
"\n"
;
class ASTNodes
{
public:
......@@ -202,7 +214,7 @@ public:
QTextStream output(&file);
out = &output;
*out << copyrightHeader <<
*out << copyrightHeader << generatedHeader <<
"\n"
"#include \"AST.h\"\n"
"#include \"ASTVisitor.h\"\n"
......@@ -339,7 +351,7 @@ public:
QTextStream output(&file);
out = &output;
*out << copyrightHeader <<
*out << copyrightHeader << generatedHeader <<
"\n"
"#include \"AST.h\"\n"
"#include \"ASTMatcher.h\"\n"
......@@ -450,6 +462,7 @@ public:
out = &output;
*out << copyrightHeader << endl
<< generatedHeader
<< "#include \"AST.h\"" << endl
<< "#include \"ASTMatcher.h\"" << endl
<< "#include \"TranslationUnit.h\"" << endl
......@@ -584,6 +597,146 @@ protected:
}
};
class CloneCPPCG: protected ASTVisitor
{
QDir _cplusplusDir;
QTextStream *out;
public:
CloneCPPCG(const QDir &cplusplusDir, TranslationUnit *unit)
: ASTVisitor(unit), _cplusplusDir(cplusplusDir), out(0)
{ }
void operator()(AST *ast)
{
QFileInfo fileInfo(_cplusplusDir, QLatin1String("ASTClone.cpp"));
QFile file(fileInfo.absoluteFilePath());
if (! file.open(QFile::WriteOnly))
return;
QTextStream output(&file);
out = &output;
*out << copyrightHeader
<< generatedHeader
<< "#include \"AST.h\"" << endl
<< "#include \"MemoryPool.h\"" << endl
<< endl
<< "using namespace CPlusPlus;" << endl
<< endl;
accept(ast);
file.close();
}
protected:
using ASTVisitor::visit;
QMap<QByteArray, ClassSpecifierAST *> classMap;
QByteArray id_cast(NameAST *name)
{
if (! name)
return QByteArray();
const Identifier *id = identifier(name->asSimpleName()->identifier_token);
return QByteArray::fromRawData(id->chars(), id->size());
}
void visitMembers(Class *klass)
{
for (unsigned i = 0; i < klass->memberCount(); ++i) {
Symbol *member = klass->memberAt(i);
if (! member->name())
continue;
const Identifier *id = member->name()->identifier();
if (! id)
continue;
const QByteArray memberName = QByteArray::fromRawData(id->chars(), id->size());
if (member->type().isUnsigned() && memberName.endsWith("_token")) {
*out << " ast->" << memberName << " = " << memberName << ";" << endl;
} else if (PointerType *ptrTy = member->type()->asPointerType()) {
if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
QByteArray typeName = namedTy->name()->identifier()->chars();
if (typeName.endsWith("ListAST")) {
*out << " for (" << typeName << " *iter = " << memberName << ", **ast_iter = &ast->" << memberName << ";" << endl
<< " iter; iter = iter->next, ast_iter = &(*ast_iter)->next)" << endl
<< " *ast_iter = new (pool) " << typeName << "((iter->value) ? iter->value->clone(pool) : 0);" << endl;
} else if (typeName.endsWith("AST")) {
*out << " if (" << memberName << ")" << endl
<< " ast->" << memberName << " = " << memberName << "->clone(pool);" << endl;
}
}
}
}
for (unsigned i = 0; i < klass->baseClassCount(); ++i) {
const QByteArray baseClassName = klass->baseClassAt(i)->identifier()->chars();
if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, 0)) {
visitMembers(baseClassSpec->symbol);
}
}
}
bool checkMethod(Symbol *cloneMethod) const
{
Declaration *decl = cloneMethod->asDeclaration();
if (! decl)
return false;
Function *funTy = decl->type()->asFunctionType();
if (! funTy)
return false;
else if (funTy->isPureVirtual())
return false;
return true;
}
virtual bool visit(ClassSpecifierAST *ast)
{
Class *klass = ast->symbol;
const QByteArray className = id_cast(ast->name);
if (! className.endsWith("AST"))
return false;
const Identifier *clone_id = control()->findOrInsertIdentifier("clone");
Symbol *cloneMethod = klass->members()->lookat(clone_id);
for (; cloneMethod; cloneMethod = cloneMethod->next()) {
if (cloneMethod->identifier() != clone_id)
continue;
if (checkMethod(cloneMethod))
break;
}
if (! cloneMethod)
return true;
classMap.insert(className, ast);
*out << className.constData() << " *" << className.constData() << "::" << "clone(MemoryPool *pool) const" << endl
<< "{" << endl
<< " " << className.constData() << " *ast = new (pool) " << className.constData() << ";" << endl;
visitMembers(klass);
*out << " return ast;" << endl
<< "}" << endl << endl;
return false;
}
};
class RemoveCastMethods: protected ASTVisitor
{
public:
......@@ -703,6 +856,9 @@ QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir)
MatcherCPPCG cg3(cplusplusDir, AST_h_document->translationUnit());
cg3(AST_h_document->translationUnit()->ast());
CloneCPPCG cg4(cplusplusDir, AST_h_document->translationUnit());
cg4(AST_h_document->translationUnit()->ast());
return astDerivedClasses;
}
......@@ -798,6 +954,7 @@ void generateASTPatternBuilder_h(const QDir &cplusplusDir)
out
<< copyrightHeader
<< generatedHeader
<< "#ifndef CPLUSPLUS_AST_PATTERN_BUILDER_H" << endl
<< "#define CPLUSPLUS_AST_PATTERN_BUILDER_H" << endl
<< endl
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment