diff options
author | hjk <qtc-committer@nokia.com> | 2009-01-26 16:19:24 +0100 |
---|---|---|
committer | hjk <qtc-committer@nokia.com> | 2009-01-26 16:19:24 +0100 |
commit | fe0533de2a634ca377c2d8a0073e0eb2cbf89abf (patch) | |
tree | 29d3d30e6cc5a1068a94097a5660bc4d133a205f /src/shared/cplusplus/Control.cpp | |
parent | c85ba53365d606192069a841ed806979f17d80bc (diff) | |
download | qt-creator-fe0533de2a634ca377c2d8a0073e0eb2cbf89abf.tar.gz |
Fixes: move all files in shared/* to src/shared/*
Diffstat (limited to 'src/shared/cplusplus/Control.cpp')
-rw-r--r-- | src/shared/cplusplus/Control.cpp | 636 |
1 files changed, 636 insertions, 0 deletions
diff --git a/src/shared/cplusplus/Control.cpp b/src/shared/cplusplus/Control.cpp new file mode 100644 index 0000000000..e44d84a1ae --- /dev/null +++ b/src/shared/cplusplus/Control.cpp @@ -0,0 +1,636 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.3, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ +// Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "Control.h" +#include "MemoryPool.h" +#include "Literals.h" +#include "LiteralTable.h" +#include "TranslationUnit.h" +#include "CoreTypes.h" +#include "Symbols.h" +#include "Names.h" +#include "Array.h" +#include <map> // ### replace me with LiteralTable +#include <string> + +CPLUSPLUS_BEGIN_NAMESPACE + +template <typename _Iterator> +static void delete_map_entries(_Iterator first, _Iterator last) +{ + for (; first != last; ++first) + delete first->second; +} + +template <typename _Map> +static void delete_map_entries(const _Map &m) +{ delete_map_entries(m.begin(), m.end()); } + +template <typename _Iterator> +static void delete_array_entries(_Iterator first, _Iterator last) +{ + for (; first != last; ++first) + delete *first; +} + +template <typename _Array> +static void delete_array_entries(const _Array &a) +{ delete_array_entries(a.begin(), a.end()); } + +class Control::Data +{ +public: + Data(Control *control) + : control(control), + translationUnit(0), + diagnosticClient(0) + { } + + ~Data() + { + // names + delete_map_entries(nameIds); + delete_map_entries(destructorNameIds); + delete_map_entries(operatorNameIds); + delete_map_entries(conversionNameIds); + delete_map_entries(qualifiedNameIds); + delete_map_entries(templateNameIds); + + // types + delete_map_entries(integerTypes); + delete_map_entries(floatTypes); + delete_map_entries(pointerToMemberTypes); + delete_map_entries(pointerTypes); + delete_map_entries(referenceTypes); + delete_map_entries(arrayTypes); + delete_map_entries(namedTypes); + + // symbols + delete_array_entries(declarations); + delete_array_entries(arguments); + delete_array_entries(functions); + delete_array_entries(baseClasses); + delete_array_entries(blocks); + delete_array_entries(classes); + delete_array_entries(namespaces); + delete_array_entries(usingNamespaceDirectives); + delete_array_entries(enums); + delete_array_entries(usingDeclarations); + } + + NameId *findOrInsertNameId(Identifier *id) + { + if (! id) + return 0; + std::map<Identifier *, NameId *>::iterator it = nameIds.lower_bound(id); + if (it == nameIds.end() || it->first != id) + it = nameIds.insert(it, std::make_pair(id, new NameId(id))); + return it->second; + } + + TemplateNameId *findOrInsertTemplateNameId(Identifier *id, + const std::vector<FullySpecifiedType> &templateArguments) + { + if (! id) + return 0; + const TemplateNameIdKey key(id, templateArguments); + std::map<TemplateNameIdKey, TemplateNameId *>::iterator it = + templateNameIds.lower_bound(key); + if (it == templateNameIds.end() || it->first != key) { + const FullySpecifiedType *args = 0; + if (templateArguments.size()) + args = &templateArguments[0]; + TemplateNameId *templ = new TemplateNameId(id, args, + templateArguments.size()); + it = templateNameIds.insert(it, std::make_pair(key, templ)); + } + return it->second; + } + + DestructorNameId *findOrInsertDestructorNameId(Identifier *id) + { + if (! id) + return 0; + std::map<Identifier *, DestructorNameId *>::iterator it = destructorNameIds.lower_bound(id); + if (it == destructorNameIds.end() || it->first != id) + it = destructorNameIds.insert(it, std::make_pair(id, new DestructorNameId(id))); + return it->second; + } + + OperatorNameId *findOrInsertOperatorNameId(int kind) + { + const int key(kind); + std::map<int, OperatorNameId *>::iterator it = operatorNameIds.lower_bound(key); + if (it == operatorNameIds.end() || it->first != key) + it = operatorNameIds.insert(it, std::make_pair(key, new OperatorNameId(kind))); + return it->second; + } + + ConversionNameId *findOrInsertConversionNameId(FullySpecifiedType type) + { + std::map<FullySpecifiedType, ConversionNameId *>::iterator it = + conversionNameIds.lower_bound(type); + if (it == conversionNameIds.end() || it->first != type) + it = conversionNameIds.insert(it, std::make_pair(type, new ConversionNameId(type))); + return it->second; + } + + QualifiedNameId *findOrInsertQualifiedNameId(const std::vector<Name *> &names, bool isGlobal) + { + const QualifiedNameIdKey key(names, isGlobal); + std::map<QualifiedNameIdKey, QualifiedNameId *>::iterator it = + qualifiedNameIds.lower_bound(key); + if (it == qualifiedNameIds.end() || it->first != key) { + QualifiedNameId *name = new QualifiedNameId(&names[0], names.size(), isGlobal); + it = qualifiedNameIds.insert(it, std::make_pair(key, name)); + } + return it->second; + } + + IntegerType *findOrInsertIntegerType(int kind) + { + const int key = int(kind); + std::map<int, IntegerType *>::iterator it = integerTypes.lower_bound(key); + if (it == integerTypes.end() || it->first != key) + it = integerTypes.insert(it, std::make_pair(key, new IntegerType(kind))); + return it->second; + } + + FloatType *findOrInsertFloatType(int kind) + { + const int key = int(kind); + std::map<int, FloatType *>::iterator it = floatTypes.lower_bound(key); + if (it == floatTypes.end() || it->first != key) + it = floatTypes.insert(it, std::make_pair(key, new FloatType(kind))); + return it->second; + } + + PointerToMemberType *findOrInsertPointerToMemberType(Name *memberName, FullySpecifiedType elementType) + { + const PointerToMemberTypeKey key(memberName, elementType); + std::map<PointerToMemberTypeKey, PointerToMemberType *>::iterator it = + pointerToMemberTypes.lower_bound(key); + if (it == pointerToMemberTypes.end() || it->first != key) + it = pointerToMemberTypes.insert(it, std::make_pair(key, new PointerToMemberType(memberName, elementType))); + return it->second; + } + + PointerType *findOrInsertPointerType(FullySpecifiedType elementType) + { + std::map<FullySpecifiedType, PointerType *>::iterator it = + pointerTypes.lower_bound(elementType); + if (it == pointerTypes.end() || it->first != elementType) + it = pointerTypes.insert(it, std::make_pair(elementType, new PointerType(elementType))); + return it->second; + } + + ReferenceType *findOrInsertReferenceType(FullySpecifiedType elementType) + { + std::map<FullySpecifiedType, ReferenceType *>::iterator it = + referenceTypes.lower_bound(elementType); + if (it == referenceTypes.end() || it->first != elementType) + it = referenceTypes.insert(it, std::make_pair(elementType, new ReferenceType(elementType))); + return it->second; + } + + ArrayType *findOrInsertArrayType(FullySpecifiedType elementType, size_t size) + { + const ArrayKey key(elementType, size); + std::map<ArrayKey, ArrayType *>::iterator it = + arrayTypes.lower_bound(key); + if (it == arrayTypes.end() || it->first != key) + it = arrayTypes.insert(it, std::make_pair(key, new ArrayType(elementType, size))); + return it->second; + } + + NamedType *findOrInsertNamedType(Name *name) + { + std::map<Name *, NamedType *>::iterator it = namedTypes.lower_bound(name); + if (it == namedTypes.end() || it->first != name) + it = namedTypes.insert(it, std::make_pair(name, new NamedType(name))); + return it->second; + } + + Declaration *newDeclaration(unsigned sourceLocation, Name *name) + { + Declaration *declaration = new Declaration(translationUnit, + sourceLocation, name); + declarations.push_back(declaration); + return declaration; + } + + Argument *newArgument(unsigned sourceLocation, Name *name) + { + Argument *argument = new Argument(translationUnit, + sourceLocation, name); + arguments.push_back(argument); + return argument; + } + + Function *newFunction(unsigned sourceLocation, Name *name) + { + Function *function = new Function(translationUnit, + sourceLocation, name); + functions.push_back(function); + return function; + } + + BaseClass *newBaseClass(unsigned sourceLocation, Name *name) + { + BaseClass *baseClass = new BaseClass(translationUnit, + sourceLocation, name); + baseClasses.push_back(baseClass); + return baseClass; + } + + Block *newBlock(unsigned sourceLocation) + { + Block *block = new Block(translationUnit, sourceLocation); + blocks.push_back(block); + return block; + } + + Class *newClass(unsigned sourceLocation, Name *name) + { + Class *klass = new Class(translationUnit, + sourceLocation, name); + classes.push_back(klass); + return klass; + } + + Namespace *newNamespace(unsigned sourceLocation, Name *name) + { + Namespace *ns = new Namespace(translationUnit, + sourceLocation, name); + namespaces.push_back(ns); + return ns; + } + + UsingNamespaceDirective *newUsingNamespaceDirective(unsigned sourceLocation, Name *name) + { + UsingNamespaceDirective *u = new UsingNamespaceDirective(translationUnit, + sourceLocation, name); + usingNamespaceDirectives.push_back(u); + return u; + } + + Enum *newEnum(unsigned sourceLocation, Name *name) + { + Enum *e = new Enum(translationUnit, + sourceLocation, name); + enums.push_back(e); + return e; + } + + UsingDeclaration *newUsingDeclaration(unsigned sourceLocation, Name *name) + { + UsingDeclaration *u = new UsingDeclaration(translationUnit, + sourceLocation, name); + usingDeclarations.push_back(u); + return u; + } + + struct TemplateNameIdKey { + Identifier *id; + std::vector<FullySpecifiedType> templateArguments; + + TemplateNameIdKey(Identifier *id, const std::vector<FullySpecifiedType> &templateArguments) + : id(id), templateArguments(templateArguments) + { } + + bool operator == (const TemplateNameIdKey &other) const + { return id == other.id && templateArguments == other.templateArguments; } + + bool operator != (const TemplateNameIdKey &other) const + { return ! operator==(other); } + + bool operator < (const TemplateNameIdKey &other) const + { + if (id == other.id) + return std::lexicographical_compare(templateArguments.begin(), + templateArguments.end(), + other.templateArguments.begin(), + other.templateArguments.end()); + return id < other.id; + } + }; + + struct QualifiedNameIdKey { + std::vector<Name *> names; + bool isGlobal; + + QualifiedNameIdKey(const std::vector<Name *> &names, bool isGlobal) : + names(names), isGlobal(isGlobal) + { } + + bool operator == (const QualifiedNameIdKey &other) const + { return isGlobal == other.isGlobal && names == other.names; } + + bool operator != (const QualifiedNameIdKey &other) const + { return ! operator==(other); } + + bool operator < (const QualifiedNameIdKey &other) const + { + if (isGlobal == other.isGlobal) + return std::lexicographical_compare(names.begin(), names.end(), + other.names.begin(), other.names.end()); + return isGlobal < other.isGlobal; + } + }; + + struct ArrayKey { + FullySpecifiedType type; + size_t size; + + ArrayKey() : + size(0) + { } + + ArrayKey(FullySpecifiedType type, size_t size) : + type(type), size(size) + { } + + bool operator == (const ArrayKey &other) const + { return type == other.type && size == other.size; } + + bool operator != (const ArrayKey &other) const + { return ! operator==(other); } + + bool operator < (const ArrayKey &other) const + { + if (type == other.type) + return size < other.size; + return type < other.type; + } + }; + + struct PointerToMemberTypeKey { + Name *memberName; + FullySpecifiedType type; + + PointerToMemberTypeKey() + : memberName(0) + { } + + PointerToMemberTypeKey(Name *memberName, FullySpecifiedType type) + : memberName(memberName), type(type) + { } + + bool operator == (const PointerToMemberTypeKey &other) const + { return memberName == other.memberName && type == other.type; } + + bool operator != (const PointerToMemberTypeKey &other) const + { return ! operator==(other); } + + bool operator < (const PointerToMemberTypeKey &other) const + { + if (memberName == other.memberName) + return type < other.type; + return memberName < other.memberName; + } + }; + + Control *control; + TranslationUnit *translationUnit; + DiagnosticClient *diagnosticClient; + LiteralTable<Identifier> identifiers; + LiteralTable<StringLiteral> stringLiterals; + LiteralTable<NumericLiteral> numericLiterals; + LiteralTable<StringLiteral> fileNames; + + // ### replace std::map with lookup tables. ASAP! + + // names + std::map<Identifier *, NameId *> nameIds; + std::map<Identifier *, DestructorNameId *> destructorNameIds; + std::map<int, OperatorNameId *> operatorNameIds; + std::map<FullySpecifiedType, ConversionNameId *> conversionNameIds; + std::map<TemplateNameIdKey, TemplateNameId *> templateNameIds; + std::map<QualifiedNameIdKey, QualifiedNameId *> qualifiedNameIds; + + // types + VoidType voidType; + std::map<int, IntegerType *> integerTypes; + std::map<int, FloatType *> floatTypes; + std::map<PointerToMemberTypeKey, PointerToMemberType *> pointerToMemberTypes; + std::map<FullySpecifiedType, PointerType *> pointerTypes; + std::map<FullySpecifiedType, ReferenceType *> referenceTypes; + std::map<ArrayKey, ArrayType *> arrayTypes; + std::map<Name *, NamedType *> namedTypes; + + // symbols + std::vector<Declaration *> declarations; + std::vector<Argument *> arguments; + std::vector<Function *> functions; + std::vector<BaseClass *> baseClasses; + std::vector<Block *> blocks; + std::vector<Class *> classes; + std::vector<Namespace *> namespaces; + std::vector<UsingNamespaceDirective *> usingNamespaceDirectives; + std::vector<Enum *> enums; + std::vector<UsingDeclaration *> usingDeclarations; +}; + +Control::Control() +{ d = new Data(this); } + +Control::~Control() +{ delete d; } + +TranslationUnit *Control::translationUnit() const +{ return d->translationUnit; } + +TranslationUnit *Control::switchTranslationUnit(TranslationUnit *unit) +{ + TranslationUnit *previousTranslationUnit = d->translationUnit; + d->translationUnit = unit; + return previousTranslationUnit; +} + +DiagnosticClient *Control::diagnosticClient() const +{ return d->diagnosticClient; } + +void Control::setDiagnosticClient(DiagnosticClient *diagnosticClient) +{ d->diagnosticClient = diagnosticClient; } + +Identifier *Control::findOrInsertIdentifier(const char *chars, unsigned size) +{ return d->identifiers.findOrInsertLiteral(chars, size); } + +Identifier *Control::findOrInsertIdentifier(const char *chars) +{ + unsigned length = std::char_traits<char>::length(chars); + return findOrInsertIdentifier(chars, length); +} + +Control::IdentifierIterator Control::firstIdentifier() const +{ return d->identifiers.begin(); } + +Control::IdentifierIterator Control::lastIdentifier() const +{ return d->identifiers.end(); } + +StringLiteral *Control::findOrInsertStringLiteral(const char *chars, unsigned size) +{ return d->stringLiterals.findOrInsertLiteral(chars, size); } + +StringLiteral *Control::findOrInsertStringLiteral(const char *chars) +{ + unsigned length = std::char_traits<char>::length(chars); + return findOrInsertStringLiteral(chars, length); +} + +NumericLiteral *Control::findOrInsertNumericLiteral(const char *chars, unsigned size) +{ return d->numericLiterals.findOrInsertLiteral(chars, size); } + +NumericLiteral *Control::findOrInsertNumericLiteral(const char *chars) +{ + unsigned length = std::char_traits<char>::length(chars); + return findOrInsertNumericLiteral(chars, length); +} + +unsigned Control::fileNameCount() const +{ return d->fileNames.size(); } + +StringLiteral *Control::fileNameAt(unsigned index) const +{ return d->fileNames.at(index); } + +StringLiteral *Control::findOrInsertFileName(const char *chars, unsigned size) +{ return d->fileNames.findOrInsertLiteral(chars, size); } + +StringLiteral *Control::findOrInsertFileName(const char *chars) +{ + unsigned length = std::char_traits<char>::length(chars); + return findOrInsertFileName(chars, length); +} + +NameId *Control::nameId(Identifier *id) +{ return d->findOrInsertNameId(id); } + +TemplateNameId *Control::templateNameId(Identifier *id, + FullySpecifiedType *const args, + unsigned argv) +{ + std::vector<FullySpecifiedType> templateArguments(args, args + argv); + return d->findOrInsertTemplateNameId(id, templateArguments); +} + +DestructorNameId *Control::destructorNameId(Identifier *id) +{ return d->findOrInsertDestructorNameId(id); } + +OperatorNameId *Control::operatorNameId(int kind) +{ return d->findOrInsertOperatorNameId(kind); } + +ConversionNameId *Control::conversionNameId(FullySpecifiedType type) +{ return d->findOrInsertConversionNameId(type); } + +QualifiedNameId *Control::qualifiedNameId(Name *const *names, + unsigned nameCount, + bool isGlobal) +{ + std::vector<Name *> classOrNamespaceNames(names, names + nameCount); + return d->findOrInsertQualifiedNameId(classOrNamespaceNames, isGlobal); +} + +VoidType *Control::voidType() +{ return &d->voidType; } + +IntegerType *Control::integerType(int kind) +{ return d->findOrInsertIntegerType(kind); } + +FloatType *Control::floatType(int kind) +{ return d->findOrInsertFloatType(kind); } + +PointerToMemberType *Control::pointerToMemberType(Name *memberName, FullySpecifiedType elementType) +{ return d->findOrInsertPointerToMemberType(memberName, elementType); } + +PointerType *Control::pointerType(FullySpecifiedType elementType) +{ return d->findOrInsertPointerType(elementType); } + +ReferenceType *Control::referenceType(FullySpecifiedType elementType) +{ return d->findOrInsertReferenceType(elementType); } + +ArrayType *Control::arrayType(FullySpecifiedType elementType, size_t size) +{ return d->findOrInsertArrayType(elementType, size); } + +NamedType *Control::namedType(Name *name) +{ return d->findOrInsertNamedType(name); } + +Argument *Control::newArgument(unsigned sourceLocation, Name *name) +{ return d->newArgument(sourceLocation, name); } + +Function *Control::newFunction(unsigned sourceLocation, Name *name) +{ return d->newFunction(sourceLocation, name); } + +Namespace *Control::newNamespace(unsigned sourceLocation, Name *name) +{ return d->newNamespace(sourceLocation, name); } + +BaseClass *Control::newBaseClass(unsigned sourceLocation, Name *name) +{ return d->newBaseClass(sourceLocation, name); } + +Class *Control::newClass(unsigned sourceLocation, Name *name) +{ return d->newClass(sourceLocation, name); } + +Enum *Control::newEnum(unsigned sourceLocation, Name *name) +{ return d->newEnum(sourceLocation, name); } + +Block *Control::newBlock(unsigned sourceLocation) +{ return d->newBlock(sourceLocation); } + +Declaration *Control::newDeclaration(unsigned sourceLocation, Name *name) +{ return d->newDeclaration(sourceLocation, name); } + +UsingNamespaceDirective *Control::newUsingNamespaceDirective(unsigned sourceLocation, + Name *name) +{ return d->newUsingNamespaceDirective(sourceLocation, name); } + +UsingDeclaration *Control::newUsingDeclaration(unsigned sourceLocation, Name *name) +{ return d->newUsingDeclaration(sourceLocation, name); } + +CPLUSPLUS_END_NAMESPACE |