Control.cpp 27.2 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2 3 4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11 12 13 14
** 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.
15
**
16
** GNU Lesser General Public License Usage
17
**
18 19 20 21 22 23
** 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.
24
**
25
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
con's avatar
con committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
// 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"
57
#include "TypeMatcher.h"
Roberto Raggi's avatar
Roberto Raggi committed
58 59
#include <map>
#include <set>
con's avatar
con committed
60

Roberto Raggi's avatar
Roberto Raggi committed
61
using namespace CPlusPlus;
con's avatar
con committed
62

Roberto Raggi's avatar
Roberto Raggi committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
namespace {

template <typename _Tp>
struct Compare;

template <> struct Compare<IntegerType>
{
    bool operator()(const IntegerType &ty, const IntegerType &otherTy) const
    { return ty.kind() < otherTy.kind(); }
};

template <> struct Compare<FloatType>
{
    bool operator()(const FloatType &ty, const FloatType &otherTy) const
    { return ty.kind() < otherTy.kind(); }
};

template <> struct Compare<PointerToMemberType>
{
    bool operator()(const PointerToMemberType &ty, const PointerToMemberType &otherTy) const
    {
        if (ty.memberName() < otherTy.memberName())
            return true;

        else if (ty.memberName() == otherTy.memberName())
            return ty.elementType() < otherTy.elementType();

        return false;
    }
};

template <> struct Compare<PointerType>
{
    bool operator()(const PointerType &ty, const PointerType &otherTy) const
    {
        return ty.elementType() < otherTy.elementType();
    }
};

template <> struct Compare<ReferenceType>
{
    bool operator()(const ReferenceType &ty, const ReferenceType &otherTy) const
    {
        return ty.elementType() < otherTy.elementType();
    }
};

template <> struct Compare<NamedType>
{
    bool operator()(const NamedType &ty, const NamedType &otherTy) const
    {
        return ty.name() < otherTy.name();
    }
};

template <> struct Compare<ArrayType>
{
    bool operator()(const ArrayType &ty, const ArrayType &otherTy) const
    {
        if (ty.size() < otherTy.size())
            return true;

        else if (ty.size() == otherTy.size())
            return ty.elementType() < otherTy.elementType();

        return false;
    }
};

template <typename _Tp>
class Table: public std::set<_Tp, Compare<_Tp> >
{
public:
    _Tp *intern(const _Tp &element)
    { return const_cast<_Tp *>(&*insert(element).first); }
};

} // end of anonymous namespace

con's avatar
con committed
142 143 144 145 146 147 148
template <typename _Iterator>
static void delete_map_entries(_Iterator first, _Iterator last)
{
    for (; first != last; ++first)
        delete first->second;
}

149 150 151 152 153 154 155
template <typename _Iterator>
static void delete_array_entries(_Iterator first, _Iterator last)
{
    for (; first != last; ++first)
        delete *first;
}

con's avatar
con committed
156 157 158 159 160 161
template <typename _Map>
static void delete_map_entries(const _Map &m)
{ delete_map_entries(m.begin(), m.end()); }

template <typename _Array>
static void delete_array_entries(const _Array &a)
162
{ delete_array_entries(a.begin(), a.end()); }
163

con's avatar
con committed
164 165 166 167 168 169
class Control::Data
{
public:
    Data(Control *control)
        : control(control),
          translationUnit(0),
Roberto Raggi's avatar
Roberto Raggi committed
170
          diagnosticClient(0)
171
    {}
con's avatar
con committed
172 173 174 175 176 177 178 179 180 181 182 183

    ~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);

        // symbols
184
        delete_array_entries(symbols);
con's avatar
con committed
185 186
    }

Roberto Raggi's avatar
Roberto Raggi committed
187
    const NameId *findOrInsertNameId(const Identifier *id)
con's avatar
con committed
188 189 190
    {
        if (! id)
            return 0;
Roberto Raggi's avatar
Roberto Raggi committed
191
        std::map<const Identifier *, const NameId *>::iterator it = nameIds.lower_bound(id);
con's avatar
con committed
192 193 194 195 196
        if (it == nameIds.end() || it->first != id)
            it = nameIds.insert(it, std::make_pair(id, new NameId(id)));
        return it->second;
    }

Roberto Raggi's avatar
Roberto Raggi committed
197 198
    const TemplateNameId *findOrInsertTemplateNameId(const Identifier *id,
                                                     const std::vector<FullySpecifiedType> &templateArguments)
con's avatar
con committed
199 200 201 202
    {
        if (! id)
            return 0;
        const TemplateNameIdKey key(id, templateArguments);
Roberto Raggi's avatar
Roberto Raggi committed
203
        std::map<TemplateNameIdKey, const TemplateNameId *>::iterator it =
con's avatar
con committed
204 205 206 207 208
                templateNameIds.lower_bound(key);
        if (it == templateNameIds.end() || it->first != key) {
            const FullySpecifiedType *args = 0;
            if (templateArguments.size())
                args = &templateArguments[0];
Roberto Raggi's avatar
Roberto Raggi committed
209
            const TemplateNameId *templ = new TemplateNameId(id, args, templateArguments.size());
con's avatar
con committed
210 211 212 213 214
            it = templateNameIds.insert(it, std::make_pair(key, templ));
        }
        return it->second;
    }

Roberto Raggi's avatar
Roberto Raggi committed
215
    const DestructorNameId *findOrInsertDestructorNameId(const Identifier *id)
con's avatar
con committed
216 217 218
    {
        if (! id)
            return 0;
Roberto Raggi's avatar
Roberto Raggi committed
219
        std::map<const Identifier *, const DestructorNameId *>::iterator it = destructorNameIds.lower_bound(id);
con's avatar
con committed
220 221 222 223 224
        if (it == destructorNameIds.end() || it->first != id)
            it = destructorNameIds.insert(it, std::make_pair(id, new DestructorNameId(id)));
        return it->second;
    }

Roberto Raggi's avatar
Roberto Raggi committed
225
    const OperatorNameId *findOrInsertOperatorNameId(int kind)
con's avatar
con committed
226 227
    {
        const int key(kind);
Roberto Raggi's avatar
Roberto Raggi committed
228
        std::map<int, const OperatorNameId *>::iterator it = operatorNameIds.lower_bound(key);
con's avatar
con committed
229 230 231 232 233
        if (it == operatorNameIds.end() || it->first != key)
            it = operatorNameIds.insert(it, std::make_pair(key, new OperatorNameId(kind)));
        return it->second;
    }

Roberto Raggi's avatar
Roberto Raggi committed
234
    const ConversionNameId *findOrInsertConversionNameId(const FullySpecifiedType &type)
con's avatar
con committed
235
    {
Roberto Raggi's avatar
Roberto Raggi committed
236
        std::map<FullySpecifiedType, const ConversionNameId *>::iterator it =
con's avatar
con committed
237 238 239 240 241 242
                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;
    }

Roberto Raggi's avatar
Roberto Raggi committed
243
    const QualifiedNameId *findOrInsertQualifiedNameId(const std::vector<const Name *> &names, bool isGlobal)
con's avatar
con committed
244 245
    {
        const QualifiedNameIdKey key(names, isGlobal);
Roberto Raggi's avatar
Roberto Raggi committed
246
        std::map<QualifiedNameIdKey, const QualifiedNameId *>::iterator it =
con's avatar
con committed
247 248
                qualifiedNameIds.lower_bound(key);
        if (it == qualifiedNameIds.end() || it->first != key) {
Roberto Raggi's avatar
Roberto Raggi committed
249
            const QualifiedNameId *name = new QualifiedNameId(&names[0], names.size(), isGlobal);
con's avatar
con committed
250 251 252 253 254
            it = qualifiedNameIds.insert(it, std::make_pair(key, name));
        }
        return it->second;
    }

Roberto Raggi's avatar
Roberto Raggi committed
255
    const SelectorNameId *findOrInsertSelectorNameId(const std::vector<const Name *> &names, bool hasArguments)
256 257
    {
        const SelectorNameIdKey key(names, hasArguments);
Roberto Raggi's avatar
Roberto Raggi committed
258
        std::map<SelectorNameIdKey, const SelectorNameId *>::iterator it = selectorNameIds.lower_bound(key);
259 260 261 262 263
        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;
    }

con's avatar
con committed
264 265
    IntegerType *findOrInsertIntegerType(int kind)
    {
Roberto Raggi's avatar
Roberto Raggi committed
266
        return integerTypes.intern(IntegerType(kind));
con's avatar
con committed
267 268 269 270
    }

    FloatType *findOrInsertFloatType(int kind)
    {
Roberto Raggi's avatar
Roberto Raggi committed
271
        return floatTypes.intern(FloatType(kind));
con's avatar
con committed
272 273
    }

Roberto Raggi's avatar
Roberto Raggi committed
274
    PointerToMemberType *findOrInsertPointerToMemberType(const Name *memberName, const FullySpecifiedType &elementType)
con's avatar
con committed
275
    {
Roberto Raggi's avatar
Roberto Raggi committed
276
        return pointerToMemberTypes.intern(PointerToMemberType(memberName, elementType));
con's avatar
con committed
277 278
    }

279
    PointerType *findOrInsertPointerType(const FullySpecifiedType &elementType)
con's avatar
con committed
280
    {
Roberto Raggi's avatar
Roberto Raggi committed
281
        return pointerTypes.intern(PointerType(elementType));
con's avatar
con committed
282 283
    }

284
    ReferenceType *findOrInsertReferenceType(const FullySpecifiedType &elementType)
con's avatar
con committed
285
    {
Roberto Raggi's avatar
Roberto Raggi committed
286
        return referenceTypes.intern(ReferenceType(elementType));
con's avatar
con committed
287 288
    }

289
    ArrayType *findOrInsertArrayType(const FullySpecifiedType &elementType, unsigned size)
con's avatar
con committed
290
    {
Roberto Raggi's avatar
Roberto Raggi committed
291
        return arrayTypes.intern(ArrayType(elementType, size));
con's avatar
con committed
292 293
    }

Roberto Raggi's avatar
Roberto Raggi committed
294
    NamedType *findOrInsertNamedType(const Name *name)
con's avatar
con committed
295
    {
Roberto Raggi's avatar
Roberto Raggi committed
296
        return namedTypes.intern(NamedType(name));
con's avatar
con committed
297 298
    }

Roberto Raggi's avatar
Roberto Raggi committed
299
    Declaration *newDeclaration(unsigned sourceLocation, const Name *name)
con's avatar
con committed
300 301 302
    {
        Declaration *declaration = new Declaration(translationUnit,
                                                   sourceLocation, name);
303
        symbols.push_back(declaration);
con's avatar
con committed
304 305 306
        return declaration;
    }

Roberto Raggi's avatar
Roberto Raggi committed
307
    Argument *newArgument(unsigned sourceLocation, const Name *name)
con's avatar
con committed
308 309 310
    {
        Argument *argument = new Argument(translationUnit,
                                          sourceLocation, name);
311
        symbols.push_back(argument);
con's avatar
con committed
312 313 314
        return argument;
    }

Roberto Raggi's avatar
Roberto Raggi committed
315
    Function *newFunction(unsigned sourceLocation, const Name *name)
con's avatar
con committed
316 317 318
    {
        Function *function = new Function(translationUnit,
                                          sourceLocation, name);
319
        symbols.push_back(function);
con's avatar
con committed
320 321 322
        return function;
    }

Roberto Raggi's avatar
Roberto Raggi committed
323
    BaseClass *newBaseClass(unsigned sourceLocation, const Name *name)
con's avatar
con committed
324 325 326
    {
        BaseClass *baseClass = new BaseClass(translationUnit,
                                             sourceLocation, name);
327
        symbols.push_back(baseClass);
con's avatar
con committed
328 329 330 331 332 333
        return baseClass;
    }

    Block *newBlock(unsigned sourceLocation)
    {
        Block *block = new Block(translationUnit, sourceLocation);
334
        symbols.push_back(block);
con's avatar
con committed
335 336 337
        return block;
    }

Roberto Raggi's avatar
Roberto Raggi committed
338
    Class *newClass(unsigned sourceLocation, const Name *name)
con's avatar
con committed
339 340 341
    {
        Class *klass = new Class(translationUnit,
                                 sourceLocation, name);
342
        symbols.push_back(klass);
con's avatar
con committed
343 344 345
        return klass;
    }

Roberto Raggi's avatar
Roberto Raggi committed
346
    Namespace *newNamespace(unsigned sourceLocation, const Name *name)
con's avatar
con committed
347 348 349
    {
        Namespace *ns = new Namespace(translationUnit,
                                      sourceLocation, name);
350
        symbols.push_back(ns);
con's avatar
con committed
351 352 353
        return ns;
    }

Roberto Raggi's avatar
Roberto Raggi committed
354
    UsingNamespaceDirective *newUsingNamespaceDirective(unsigned sourceLocation, const Name *name)
con's avatar
con committed
355 356 357
    {
        UsingNamespaceDirective *u = new UsingNamespaceDirective(translationUnit,
                                                                 sourceLocation, name);
358
        symbols.push_back(u);
con's avatar
con committed
359 360 361
        return u;
    }

Roberto Raggi's avatar
Roberto Raggi committed
362
    ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, const Name *name)
363 364 365
    {
        ForwardClassDeclaration *c = new ForwardClassDeclaration(translationUnit,
                                                                 sourceLocation, name);
366
        symbols.push_back(c);
367 368 369
        return c;
    }

Roberto Raggi's avatar
Roberto Raggi committed
370
    ObjCBaseClass *newObjCBaseClass(unsigned sourceLocation, const Name *name)
371 372
    {
        ObjCBaseClass *c = new ObjCBaseClass(translationUnit, sourceLocation, name);
373
        symbols.push_back(c);
374 375 376
        return c;
    }

Roberto Raggi's avatar
Roberto Raggi committed
377
    ObjCBaseProtocol *newObjCBaseProtocol(unsigned sourceLocation, const Name *name)
378 379
    {
        ObjCBaseProtocol *p = new ObjCBaseProtocol(translationUnit, sourceLocation, name);
380
        symbols.push_back(p);
381 382 383
        return p;
    }

Roberto Raggi's avatar
Roberto Raggi committed
384
    ObjCClass *newObjCClass(unsigned sourceLocation, const Name *name)
385 386
    {
        ObjCClass *c = new ObjCClass(translationUnit, sourceLocation, name);
387
        symbols.push_back(c);
388 389 390
        return c;
    }

Roberto Raggi's avatar
Roberto Raggi committed
391
    ObjCForwardClassDeclaration *newObjCForwardClassDeclaration(unsigned sourceLocation, const Name *name)
392 393
    {
        ObjCForwardClassDeclaration *fwd = new ObjCForwardClassDeclaration(translationUnit, sourceLocation, name);
394
        symbols.push_back(fwd);
395 396 397
        return fwd;
    }

Roberto Raggi's avatar
Roberto Raggi committed
398
    ObjCProtocol *newObjCProtocol(unsigned sourceLocation, const Name *name)
399 400
    {
        ObjCProtocol *p = new ObjCProtocol(translationUnit, sourceLocation, name);
401
        symbols.push_back(p);
402 403 404
        return p;
    }

Roberto Raggi's avatar
Roberto Raggi committed
405
    ObjCForwardProtocolDeclaration *newObjCForwardProtocolDeclaration(unsigned sourceLocation, const Name *name)
406 407
    {
        ObjCForwardProtocolDeclaration *fwd = new ObjCForwardProtocolDeclaration(translationUnit, sourceLocation, name);
408
        symbols.push_back(fwd);
409 410 411
        return fwd;
    }

Roberto Raggi's avatar
Roberto Raggi committed
412
    ObjCMethod *newObjCMethod(unsigned sourceLocation, const Name *name)
413 414
    {
        ObjCMethod *method = new ObjCMethod(translationUnit, sourceLocation, name);
415
        symbols.push_back(method);
416 417 418
        return method;
    }

Roberto Raggi's avatar
Roberto Raggi committed
419
    ObjCPropertyDeclaration *newObjCPropertyDeclaration(unsigned sourceLocation, const Name *name)
420 421
    {
        ObjCPropertyDeclaration *decl = new ObjCPropertyDeclaration(translationUnit, sourceLocation, name);
422
        symbols.push_back(decl);
423 424 425
        return decl;
    }

Roberto Raggi's avatar
Roberto Raggi committed
426
    Enum *newEnum(unsigned sourceLocation, const Name *name)
con's avatar
con committed
427 428 429
    {
        Enum *e = new Enum(translationUnit,
                           sourceLocation, name);
430
        symbols.push_back(e);
con's avatar
con committed
431 432 433
        return e;
    }

Roberto Raggi's avatar
Roberto Raggi committed
434
    UsingDeclaration *newUsingDeclaration(unsigned sourceLocation, const Name *name)
con's avatar
con committed
435 436 437
    {
        UsingDeclaration *u = new UsingDeclaration(translationUnit,
                                                   sourceLocation, name);
438
        symbols.push_back(u);
con's avatar
con committed
439 440 441 442
        return u;
    }

    struct TemplateNameIdKey {
Roberto Raggi's avatar
Roberto Raggi committed
443
        const Identifier *id;
con's avatar
con committed
444 445
        std::vector<FullySpecifiedType> templateArguments;

Roberto Raggi's avatar
Roberto Raggi committed
446
        TemplateNameIdKey(const Identifier *id, const std::vector<FullySpecifiedType> &templateArguments)
con's avatar
con committed
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
            : 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 {
Roberto Raggi's avatar
Roberto Raggi committed
468
        std::vector<const Name *> names;
con's avatar
con committed
469 470
        bool isGlobal;

Roberto Raggi's avatar
Roberto Raggi committed
471
        QualifiedNameIdKey(const std::vector<const Name *> &names, bool isGlobal) :
con's avatar
con committed
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
            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;
        }
    };

490
    struct SelectorNameIdKey {
Roberto Raggi's avatar
Roberto Raggi committed
491
        std::vector<const Name *> _names;
492 493
        bool _hasArguments;

Roberto Raggi's avatar
Roberto Raggi committed
494
        SelectorNameIdKey(const std::vector<const Name *> &names, bool hasArguments): _names(names), _hasArguments(hasArguments) {}
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510

        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;
        }
    };

con's avatar
con committed
511 512 513
    Control *control;
    TranslationUnit *translationUnit;
    DiagnosticClient *diagnosticClient;
514 515 516

    TypeMatcher matcher;

con's avatar
con committed
517 518 519 520 521 522 523
    LiteralTable<Identifier> identifiers;
    LiteralTable<StringLiteral> stringLiterals;
    LiteralTable<NumericLiteral> numericLiterals;

    // ### replace std::map with lookup tables. ASAP!

    // names
Roberto Raggi's avatar
Roberto Raggi committed
524 525 526 527 528 529 530
    std::map<const Identifier *, const NameId *> nameIds;
    std::map<const Identifier *, const DestructorNameId *> destructorNameIds;
    std::map<int, const OperatorNameId *> operatorNameIds;
    std::map<FullySpecifiedType, const ConversionNameId *> conversionNameIds;
    std::map<TemplateNameIdKey, const TemplateNameId *> templateNameIds;
    std::map<QualifiedNameIdKey, const QualifiedNameId *> qualifiedNameIds;
    std::map<SelectorNameIdKey, const SelectorNameId *> selectorNameIds;
con's avatar
con committed
531 532 533

    // types
    VoidType voidType;
Roberto Raggi's avatar
Roberto Raggi committed
534 535 536 537 538 539 540
    Table<IntegerType> integerTypes;
    Table<FloatType> floatTypes;
    Table<PointerToMemberType> pointerToMemberTypes;
    Table<PointerType> pointerTypes;
    Table<ReferenceType> referenceTypes;
    Table<ArrayType> arrayTypes;
    Table<NamedType> namedTypes;
con's avatar
con committed
541 542

    // symbols
543
    std::vector<Symbol *> symbols;
544 545

    // ObjC context keywords:
Roberto Raggi's avatar
Roberto Raggi committed
546 547 548 549 550 551 552 553
    const Identifier *objcGetterId;
    const Identifier *objcSetterId;
    const Identifier *objcReadwriteId;
    const Identifier *objcReadonlyId;
    const Identifier *objcAssignId;
    const Identifier *objcRetainId;
    const Identifier *objcCopyId;
    const Identifier *objcNonatomicId;
con's avatar
con committed
554 555 556
};

Control::Control()
557 558 559 560 561 562 563 564 565 566 567 568
{
    d = new Data(this);

    d->objcGetterId = findOrInsertIdentifier("getter");
    d->objcSetterId = findOrInsertIdentifier("setter");
    d->objcReadwriteId = findOrInsertIdentifier("readwrite");
    d->objcReadonlyId = findOrInsertIdentifier("readonly");
    d->objcAssignId = findOrInsertIdentifier("assign");
    d->objcRetainId = findOrInsertIdentifier("retain");
    d->objcCopyId = findOrInsertIdentifier("copy");
    d->objcNonatomicId = findOrInsertIdentifier("nonatomic");
}
con's avatar
con committed
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588

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; }

Roberto Raggi's avatar
Roberto Raggi committed
589
const Identifier *Control::findIdentifier(const char *chars, unsigned size) const
590 591
{ return d->identifiers.findLiteral(chars, size); }

Roberto Raggi's avatar
Roberto Raggi committed
592
const Identifier *Control::findOrInsertIdentifier(const char *chars, unsigned size)
con's avatar
con committed
593 594
{ return d->identifiers.findOrInsertLiteral(chars, size); }

Roberto Raggi's avatar
Roberto Raggi committed
595
const Identifier *Control::findOrInsertIdentifier(const char *chars)
con's avatar
con committed
596
{
Roberto Raggi's avatar
Roberto Raggi committed
597
    unsigned length = std::strlen(chars);
con's avatar
con committed
598 599 600
    return findOrInsertIdentifier(chars, length);
}

601 602 603 604 605 606
Control::IdentifierIterator Control::firstIdentifier() const
{ return d->identifiers.begin(); }

Control::IdentifierIterator Control::lastIdentifier() const
{ return d->identifiers.end(); }

607 608 609 610 611 612 613 614 615 616 617 618
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(); }

Roberto Raggi's avatar
Roberto Raggi committed
619
const StringLiteral *Control::findOrInsertStringLiteral(const char *chars, unsigned size)
con's avatar
con committed
620 621
{ return d->stringLiterals.findOrInsertLiteral(chars, size); }

Roberto Raggi's avatar
Roberto Raggi committed
622
const StringLiteral *Control::findOrInsertStringLiteral(const char *chars)
con's avatar
con committed
623
{
Roberto Raggi's avatar
Roberto Raggi committed
624
    unsigned length = std::strlen(chars);
con's avatar
con committed
625 626 627
    return findOrInsertStringLiteral(chars, length);
}

Roberto Raggi's avatar
Roberto Raggi committed
628
const NumericLiteral *Control::findOrInsertNumericLiteral(const char *chars, unsigned size)
con's avatar
con committed
629 630
{ return d->numericLiterals.findOrInsertLiteral(chars, size); }

Roberto Raggi's avatar
Roberto Raggi committed
631
const NumericLiteral *Control::findOrInsertNumericLiteral(const char *chars)
con's avatar
con committed
632
{
Roberto Raggi's avatar
Roberto Raggi committed
633
    unsigned length = std::strlen(chars);
con's avatar
con committed
634 635 636
    return findOrInsertNumericLiteral(chars, length);
}

Roberto Raggi's avatar
Roberto Raggi committed
637
const NameId *Control::nameId(const Identifier *id)
con's avatar
con committed
638 639
{ return d->findOrInsertNameId(id); }

Roberto Raggi's avatar
Roberto Raggi committed
640 641 642
const TemplateNameId *Control::templateNameId(const Identifier *id,
                                              const FullySpecifiedType *const args,
                                              unsigned argv)
con's avatar
con committed
643 644 645 646 647
{
    std::vector<FullySpecifiedType> templateArguments(args, args + argv);
    return d->findOrInsertTemplateNameId(id, templateArguments);
}

Roberto Raggi's avatar
Roberto Raggi committed
648
const DestructorNameId *Control::destructorNameId(const Identifier *id)
con's avatar
con committed
649 650
{ return d->findOrInsertDestructorNameId(id); }

Roberto Raggi's avatar
Roberto Raggi committed
651
const OperatorNameId *Control::operatorNameId(int kind)
con's avatar
con committed
652 653
{ return d->findOrInsertOperatorNameId(kind); }

Roberto Raggi's avatar
Roberto Raggi committed
654
const ConversionNameId *Control::conversionNameId(const FullySpecifiedType &type)
con's avatar
con committed
655 656
{ return d->findOrInsertConversionNameId(type); }

Roberto Raggi's avatar
Roberto Raggi committed
657 658 659
const QualifiedNameId *Control::qualifiedNameId(const Name *const *names,
                                                unsigned nameCount,
                                                bool isGlobal)
con's avatar
con committed
660
{
Roberto Raggi's avatar
Roberto Raggi committed
661
    std::vector<const Name *> classOrNamespaceNames(names, names + nameCount);
con's avatar
con committed
662 663 664
    return d->findOrInsertQualifiedNameId(classOrNamespaceNames, isGlobal);
}

Roberto Raggi's avatar
Roberto Raggi committed
665 666 667
const SelectorNameId *Control::selectorNameId(const Name *const *names,
                                              unsigned nameCount,
                                              bool hasArguments)
668
{
Roberto Raggi's avatar
Roberto Raggi committed
669
    std::vector<const Name *> selectorNames(names, names + nameCount);
670 671 672 673
    return d->findOrInsertSelectorNameId(selectorNames, hasArguments);
}


con's avatar
con committed
674 675 676 677 678 679 680 681 682
VoidType *Control::voidType()
{ return &d->voidType; }

IntegerType *Control::integerType(int kind)
{ return d->findOrInsertIntegerType(kind); }

FloatType *Control::floatType(int kind)
{ return d->findOrInsertFloatType(kind); }

Roberto Raggi's avatar
Roberto Raggi committed
683
PointerToMemberType *Control::pointerToMemberType(const Name *memberName, const FullySpecifiedType &elementType)
con's avatar
con committed
684 685
{ return d->findOrInsertPointerToMemberType(memberName, elementType); }

686
PointerType *Control::pointerType(const FullySpecifiedType &elementType)
con's avatar
con committed
687 688
{ return d->findOrInsertPointerType(elementType); }

689
ReferenceType *Control::referenceType(const FullySpecifiedType &elementType)
con's avatar
con committed
690 691
{ return d->findOrInsertReferenceType(elementType); }

692
ArrayType *Control::arrayType(const FullySpecifiedType &elementType, unsigned size)
con's avatar
con committed
693 694
{ return d->findOrInsertArrayType(elementType, size); }

Roberto Raggi's avatar
Roberto Raggi committed
695
NamedType *Control::namedType(const Name *name)
con's avatar
con committed
696 697
{ return d->findOrInsertNamedType(name); }

Roberto Raggi's avatar
Roberto Raggi committed
698
Argument *Control::newArgument(unsigned sourceLocation, const Name *name)
con's avatar
con committed
699 700
{ return d->newArgument(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
701
Function *Control::newFunction(unsigned sourceLocation, const Name *name)
con's avatar
con committed
702 703
{ return d->newFunction(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
704
Namespace *Control::newNamespace(unsigned sourceLocation, const Name *name)
con's avatar
con committed
705 706
{ return d->newNamespace(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
707
BaseClass *Control::newBaseClass(unsigned sourceLocation, const Name *name)
con's avatar
con committed
708 709
{ return d->newBaseClass(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
710
Class *Control::newClass(unsigned sourceLocation, const Name *name)
con's avatar
con committed
711 712
{ return d->newClass(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
713
Enum *Control::newEnum(unsigned sourceLocation, const Name *name)
con's avatar
con committed
714 715 716 717 718
{ return d->newEnum(sourceLocation, name); }

Block *Control::newBlock(unsigned sourceLocation)
{ return d->newBlock(sourceLocation); }

Roberto Raggi's avatar
Roberto Raggi committed
719
Declaration *Control::newDeclaration(unsigned sourceLocation, const Name *name)
con's avatar
con committed
720 721 722
{ return d->newDeclaration(sourceLocation, name); }

UsingNamespaceDirective *Control::newUsingNamespaceDirective(unsigned sourceLocation,
Roberto Raggi's avatar
Roberto Raggi committed
723
                                                                const Name *name)
con's avatar
con committed
724 725
{ return d->newUsingNamespaceDirective(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
726
UsingDeclaration *Control::newUsingDeclaration(unsigned sourceLocation, const Name *name)
con's avatar
con committed
727 728
{ return d->newUsingDeclaration(sourceLocation, name); }

729
ForwardClassDeclaration *Control::newForwardClassDeclaration(unsigned sourceLocation,
Roberto Raggi's avatar
Roberto Raggi committed
730
                                                             const Name *name)
731 732
{ return d->newForwardClassDeclaration(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
733
ObjCBaseClass *Control::newObjCBaseClass(unsigned sourceLocation, const Name *name)
734 735
{ return d->newObjCBaseClass(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
736
ObjCBaseProtocol *Control::newObjCBaseProtocol(unsigned sourceLocation, const Name *name)
737 738
{ return d->newObjCBaseProtocol(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
739
ObjCClass *Control::newObjCClass(unsigned sourceLocation, const Name *name)
740 741
{ return d->newObjCClass(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
742
ObjCForwardClassDeclaration *Control::newObjCForwardClassDeclaration(unsigned sourceLocation, const Name *name)
743 744
{ return d->newObjCForwardClassDeclaration(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
745
ObjCProtocol *Control::newObjCProtocol(unsigned sourceLocation, const Name *name)
746 747
{ return d->newObjCProtocol(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
748
ObjCForwardProtocolDeclaration *Control::newObjCForwardProtocolDeclaration(unsigned sourceLocation, const Name *name)
749
{ return d->newObjCForwardProtocolDeclaration(sourceLocation, name); }
750

Roberto Raggi's avatar
Roberto Raggi committed
751
ObjCMethod *Control::newObjCMethod(unsigned sourceLocation, const Name *name)
752 753
{ return d->newObjCMethod(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
754
ObjCPropertyDeclaration *Control::newObjCPropertyDeclaration(unsigned sourceLocation, const Name *name)
755 756
{ return d->newObjCPropertyDeclaration(sourceLocation, name); }

Roberto Raggi's avatar
Roberto Raggi committed
757
const Identifier *Control::objcGetterId() const
758 759
{ return d->objcGetterId; }

Roberto Raggi's avatar
Roberto Raggi committed
760
const Identifier *Control::objcSetterId() const
761 762
{ return d->objcSetterId; }

Roberto Raggi's avatar
Roberto Raggi committed
763
const Identifier *Control::objcReadwriteId() const
764 765
{ return d->objcReadwriteId; }

Roberto Raggi's avatar
Roberto Raggi committed
766
const Identifier *Control::objcReadonlyId() const
767 768
{ return d->objcReadonlyId; }

Roberto Raggi's avatar
Roberto Raggi committed
769
const Identifier *Control::objcAssignId() const
770 771
{ return d->objcAssignId; }

Roberto Raggi's avatar
Roberto Raggi committed
772
const Identifier *Control::objcRetainId() const
773 774
{ return d->objcRetainId; }

Roberto Raggi's avatar
Roberto Raggi committed
775
const Identifier *Control::objcCopyId() const
776
{ return d->objcCopyId; }
Roberto Raggi's avatar
Roberto Raggi committed
777

Roberto Raggi's avatar
Roberto Raggi committed
778
const Identifier *Control::objcNonatomicId() const
779
{ return d->objcNonatomicId; }