2009-02-25 09:15:00 +01:00
|
|
|
/**************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-06-17 00:01:27 +10:00
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Commercial Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
|
|
|
** accordance with the Qt Commercial License Agreement provided with the
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
** a written agreement between you and Nokia.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** GNU Lesser General Public License Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
|
|
** General Public License version 2.1 as published by the Free Software
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** If you are unsure which license is appropriate for your use, please
|
2009-08-14 09:30:56 +02:00
|
|
|
** contact the sales department at http://qt.nokia.com/contact.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
**************************************************************************/
|
2008-12-02 12:01:29 +01:00
|
|
|
// 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 "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>
|
|
|
|
|
2009-10-20 11:21:25 +02:00
|
|
|
using namespace CPlusPlus;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-09-30 16:25:20 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
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),
|
2009-10-07 13:56:59 +02:00
|
|
|
diagnosticClient(0)
|
2008-12-02 12:01:29 +01:00
|
|
|
{ }
|
|
|
|
|
|
|
|
~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);
|
2009-02-16 15:43:24 +01:00
|
|
|
delete_array_entries(classForwardDeclarations);
|
2009-10-05 18:02:01 +02:00
|
|
|
delete_array_entries(objcBaseClasses);
|
|
|
|
delete_array_entries(objcBaseProtocols);
|
2009-07-28 16:34:15 +02:00
|
|
|
delete_array_entries(objcClasses);
|
|
|
|
delete_array_entries(objcProtocols);
|
|
|
|
delete_array_entries(objcForwardClassDeclarations);
|
|
|
|
delete_array_entries(objcForwardProtocolDeclarations);
|
2009-08-05 18:30:18 +02:00
|
|
|
delete_array_entries(objcMethods);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2009-07-31 16:03:48 +02:00
|
|
|
SelectorNameId *findOrInsertSelectorNameId(const std::vector<Name *> &names, bool hasArguments)
|
|
|
|
{
|
|
|
|
const SelectorNameIdKey key(names, hasArguments);
|
|
|
|
std::map<SelectorNameIdKey, SelectorNameId *>::iterator it = selectorNameIds.lower_bound(key);
|
|
|
|
if (it == selectorNameIds.end() || it->first != key)
|
|
|
|
it = selectorNameIds.insert(it, std::make_pair(key, new SelectorNameId(&names[0], names.size(), hasArguments)));
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2009-02-16 15:43:24 +01:00
|
|
|
ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, Name *name)
|
|
|
|
{
|
|
|
|
ForwardClassDeclaration *c = new ForwardClassDeclaration(translationUnit,
|
|
|
|
sourceLocation, name);
|
|
|
|
classForwardDeclarations.push_back(c);
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2009-10-05 18:02:01 +02:00
|
|
|
ObjCBaseClass *newObjCBaseClass(unsigned sourceLocation, Name *name)
|
|
|
|
{
|
|
|
|
ObjCBaseClass *c = new ObjCBaseClass(translationUnit, sourceLocation, name);
|
|
|
|
objcBaseClasses.push_back(c);
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCBaseProtocol *newObjCBaseProtocol(unsigned sourceLocation, Name *name)
|
|
|
|
{
|
|
|
|
ObjCBaseProtocol *p = new ObjCBaseProtocol(translationUnit, sourceLocation, name);
|
|
|
|
objcBaseProtocols.push_back(p);
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2009-07-28 16:34:15 +02:00
|
|
|
ObjCClass *newObjCClass(unsigned sourceLocation, Name *name)
|
|
|
|
{
|
|
|
|
ObjCClass *c = new ObjCClass(translationUnit, sourceLocation, name);
|
|
|
|
objcClasses.push_back(c);
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCForwardClassDeclaration *newObjCForwardClassDeclaration(unsigned sourceLocation, Name *name)
|
|
|
|
{
|
|
|
|
ObjCForwardClassDeclaration *fwd = new ObjCForwardClassDeclaration(translationUnit, sourceLocation, name);
|
|
|
|
objcForwardClassDeclarations.push_back(fwd);
|
|
|
|
return fwd;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCProtocol *newObjCProtocol(unsigned sourceLocation, Name *name)
|
|
|
|
{
|
|
|
|
ObjCProtocol *p = new ObjCProtocol(translationUnit, sourceLocation, name);
|
|
|
|
objcProtocols.push_back(p);
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCForwardProtocolDeclaration *newObjCForwardProtocolDeclaration(unsigned sourceLocation, Name *name)
|
|
|
|
{
|
|
|
|
ObjCForwardProtocolDeclaration *fwd = new ObjCForwardProtocolDeclaration(translationUnit, sourceLocation, name);
|
|
|
|
objcForwardProtocolDeclarations.push_back(fwd);
|
|
|
|
return fwd;
|
|
|
|
}
|
|
|
|
|
2009-08-05 18:30:18 +02:00
|
|
|
ObjCMethod *newObjCMethod(unsigned sourceLocation, Name *name)
|
|
|
|
{
|
|
|
|
ObjCMethod *method = new ObjCMethod(translationUnit, sourceLocation, name);
|
|
|
|
objcMethods.push_back(method);
|
|
|
|
return method;
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-31 16:03:48 +02:00
|
|
|
struct SelectorNameIdKey {
|
|
|
|
std::vector<Name *> _names;
|
|
|
|
bool _hasArguments;
|
|
|
|
|
|
|
|
SelectorNameIdKey(const std::vector<Name *> &names, bool hasArguments): _names(names), _hasArguments(hasArguments) {}
|
|
|
|
|
|
|
|
bool operator==(const SelectorNameIdKey &other) const
|
|
|
|
{ return _names == other._names && _hasArguments == other._hasArguments; }
|
|
|
|
|
|
|
|
bool operator!=(const SelectorNameIdKey &other) const
|
|
|
|
{ return !operator==(other); }
|
|
|
|
|
|
|
|
bool operator<(const SelectorNameIdKey &other) const
|
|
|
|
{
|
|
|
|
if (_hasArguments == other._hasArguments)
|
|
|
|
return std::lexicographical_compare(_names.begin(), _names.end(), other._names.begin(), other._names.end());
|
|
|
|
else
|
|
|
|
return _hasArguments < other._hasArguments;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
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;
|
|
|
|
|
|
|
|
// ### 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;
|
2009-07-31 16:03:48 +02:00
|
|
|
std::map<SelectorNameIdKey, SelectorNameId *> selectorNameIds;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
// 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;
|
2009-02-16 15:43:24 +01:00
|
|
|
std::vector<ForwardClassDeclaration *> classForwardDeclarations;
|
2009-10-05 18:02:01 +02:00
|
|
|
std::vector<ObjCBaseClass *> objcBaseClasses;
|
|
|
|
std::vector<ObjCBaseProtocol *> objcBaseProtocols;
|
2009-07-28 16:34:15 +02:00
|
|
|
std::vector<ObjCClass *> objcClasses;
|
|
|
|
std::vector<ObjCProtocol *> objcProtocols;
|
|
|
|
std::vector<ObjCForwardClassDeclaration *> objcForwardClassDeclarations;
|
|
|
|
std::vector<ObjCForwardProtocolDeclaration *> objcForwardProtocolDeclarations;
|
2009-08-05 18:30:18 +02:00
|
|
|
std::vector<ObjCMethod *> objcMethods;
|
2008-12-02 12:01:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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; }
|
|
|
|
|
2009-09-07 13:39:46 +02:00
|
|
|
Identifier *Control::findIdentifier(const char *chars, unsigned size) const
|
|
|
|
{ return d->identifiers.findLiteral(chars, size); }
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2008-12-09 09:42:17 +01:00
|
|
|
Control::IdentifierIterator Control::firstIdentifier() const
|
|
|
|
{ return d->identifiers.begin(); }
|
|
|
|
|
|
|
|
Control::IdentifierIterator Control::lastIdentifier() const
|
|
|
|
{ return d->identifiers.end(); }
|
|
|
|
|
2009-06-05 12:08:36 +02:00
|
|
|
Control::StringLiteralIterator Control::firstStringLiteral() const
|
|
|
|
{ return d->stringLiterals.begin(); }
|
|
|
|
|
|
|
|
Control::StringLiteralIterator Control::lastStringLiteral() const
|
|
|
|
{ return d->stringLiterals.end(); }
|
|
|
|
|
|
|
|
Control::NumericLiteralIterator Control::firstNumericLiteral() const
|
|
|
|
{ return d->numericLiterals.begin(); }
|
|
|
|
|
|
|
|
Control::NumericLiteralIterator Control::lastNumericLiteral() const
|
|
|
|
{ return d->numericLiterals.end(); }
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2009-07-31 16:03:48 +02:00
|
|
|
SelectorNameId *Control::selectorNameId(Name *const *names,
|
|
|
|
unsigned nameCount,
|
|
|
|
bool hasArguments)
|
|
|
|
{
|
|
|
|
std::vector<Name *> selectorNames(names, names + nameCount);
|
|
|
|
return d->findOrInsertSelectorNameId(selectorNames, hasArguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
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); }
|
|
|
|
|
2009-02-16 15:43:24 +01:00
|
|
|
ForwardClassDeclaration *Control::newForwardClassDeclaration(unsigned sourceLocation,
|
|
|
|
Name *name)
|
|
|
|
{ return d->newForwardClassDeclaration(sourceLocation, name); }
|
|
|
|
|
2009-10-05 18:02:01 +02:00
|
|
|
ObjCBaseClass *Control::newObjCBaseClass(unsigned sourceLocation, Name *name)
|
|
|
|
{ return d->newObjCBaseClass(sourceLocation, name); }
|
|
|
|
|
|
|
|
ObjCBaseProtocol *Control::newObjCBaseProtocol(unsigned sourceLocation, Name *name)
|
|
|
|
{ return d->newObjCBaseProtocol(sourceLocation, name); }
|
|
|
|
|
2009-07-28 16:34:15 +02:00
|
|
|
ObjCClass *Control::newObjCClass(unsigned sourceLocation, Name *name)
|
|
|
|
{ return d->newObjCClass(sourceLocation, name); }
|
|
|
|
|
|
|
|
ObjCForwardClassDeclaration *Control::newObjCForwardClassDeclaration(unsigned sourceLocation, Name *name)
|
|
|
|
{ return d->newObjCForwardClassDeclaration(sourceLocation, name); }
|
|
|
|
|
|
|
|
ObjCProtocol *Control::newObjCProtocol(unsigned sourceLocation, Name *name)
|
|
|
|
{ return d->newObjCProtocol(sourceLocation, name); }
|
|
|
|
|
|
|
|
ObjCForwardProtocolDeclaration *Control::newObjCForwardProtocolDeclaration(unsigned sourceLocation, Name *name)
|
|
|
|
{ return d->newObjCForwardProtocolDeclaration(sourceLocation, name); }
|
2009-02-16 15:43:24 +01:00
|
|
|
|
2009-08-05 18:30:18 +02:00
|
|
|
ObjCMethod *Control::newObjCMethod(unsigned sourceLocation, Name *name)
|
|
|
|
{ return d->newObjCMethod(sourceLocation, name); }
|
|
|
|
|
2009-10-20 11:21:25 +02:00
|
|
|
|