File: typeconversion.h

package info (click to toggle)
kdevelop 4%3A4.3.1-3
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 18,844 kB
  • sloc: cpp: 91,758; python: 1,095; lex: 422; ruby: 120; sh: 114; xml: 42; makefile: 38
file content (169 lines) | stat: -rw-r--r-- 6,345 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
57
58
59
60
61
62
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
   Copyright 2007 David Nolden <david.nolden.kdevelop@art-master.de>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#ifndef TYPECONVERSION_H
#define TYPECONVERSION_H

#include <QList>
#include <qcontainerfwd.h>

#include <language/duchain/types/abstracttype.h>
#include <language/duchain/types/indexedtype.h>
#include <util/kdevvarlengtharray.h>

#include "cppduchainexport.h"
#include <QMap>
#include <QPair>
#include <language/duchain/classmemberdeclaration.h>
#include <language/duchain/types/pointertype.h>

namespace KDevelop {
  class TopDUContext;
  class ImportTraceItem;
  class ImportTrace;
}

namespace Cpp {
using namespace KDevelop;

  class TypeConversionCache;

  enum ConversionCategories {
    LValueTransformationCategory = 1,
    QualificationAdjustmentCategory = 2,
    PromotionCategory = 4,
    ConversionCategory = 8,
    IdentityCategory = 16
  };

  ///See iso c++ draf 13.3.3.1.1
   enum ConversionRank {
     NoMatch = 0,
     Conversion,
     Promotion,
     ExactMatch,
     ConversionRankOffset ///ConversionRankOffset is used to model the ranking of implicit conversion sequences(iso c++ 13.3.3.2), it is added once to the result of user-defined conversions, and twice to the result of standard-conversions.
   };

   enum ConversionType {
     UserDefinedConversion,
     EllipsisConversion,
     StandardConversion
   };

   enum {
     MaximumConversionResult = 2*ConversionRankOffset + ExactMatch
   };

/**
 * Class that models c++ type-conversion.
 *
 * The du-chain must be locked whenever this class is used.
 *
 * @todo ellipsis(functions with arbitrary count of arguments) cannot be respected because it is not parsed yet
 * */
class KDEVCPPDUCHAIN_EXPORT TypeConversion {
  public:
    ///topContext is needed to resolve forward-declarations
    TypeConversion(const KDevelop::TopDUContext* topContext );
    virtual ~TypeConversion();
    /**
     * An implicit conversion sequence is a sequence of conversions used to convert an argument in a function call to the type of the corresponding parameter of the function being called. (iso c++ draft 13.3.3.1)
     *
     * 13.3.3.2(ranking of implicit conversion sequences) is only partially modeled.
     *
     * @param from The type from which to convert
     * @param to The type to which to convert
     * @param fromLValue Whether the from-type is explicitly an lvalue. When the from-type is a reference, it is an lvalue anyway. This especially influences whether a conversion to a non-constant reference is possible.
     * @return Whether there is an implicit conversion sequence available. 0 when no conversion is possible, else a positive number. The higher it is, the better the conversion. Maximum should be MaximumConversionResult
     **/

    uint implicitConversion( IndexedType from, IndexedType to, bool fromLValue = true, bool noUserDefinedConversion = false );

    /**
     * Returns the count of steps by which a class needed to be converted to it's base-class during the last implicit conversion.
     * Since a conversion to a base-class is still considered an exact match, this can be used to more precisely compare results.
     * */
    int baseConversionLevels() const;

    /**
     * Start/Stop type-conversion caching for the current thread. Prefer TypeConversionEnabler over calling these directly.
     */
    static void startCache();
    static void stopCache();
    
  protected:
    /**
     * iso c++ draf 13.3.3.1.1
     *
     * Warning: standardConversion(..) cannot deal with reference-types as target. That case must be treated from outside. Also reference-binding with the base-class logic etc. is not done here.
     * */
    ConversionRank standardConversion( AbstractType::Ptr from, AbstractType::Ptr to, int allowedCategories = IdentityCategory | LValueTransformationCategory | QualificationAdjustmentCategory | PromotionCategory | ConversionCategory, int maxCategories = 3 );


  private:
    
    ///Returns whether the given declaration is accessible from here
    ///@todo Does not respect the local context yet
    bool isAccessible(const ClassMemberDeclaration* decl);
    
    /**iso c++ draft 13.3.3.1.2
     *
     * @param secondConversionIsIdentity Whether the second standard-conversion should be an identity-conversion or derived-to-base-conversion
     */
    ConversionRank userDefinedConversion( AbstractType::Ptr from, AbstractType::Ptr to, bool fromLValue, bool secondConversionIsIdentity = false );

    ConversionRank pointerConversion( PointerType::Ptr from, PointerType::Ptr to );
    
    ///iso c++ draft 13.3.3.1.3
    ConversionRank ellipsisConversion( AbstractType::Ptr from, AbstractType::Ptr to );


    virtual void problem( AbstractType::Ptr from, AbstractType::Ptr to, const QString&  desc );


    /**Identity-conversion:
     * This represents an identity-conversion in the context of copying. That means that top-level cv-qualifiers are ignored.
     *
     * @return Whether the types are same except for cv-qualification */

    bool identityConversion( AbstractType::Ptr from, AbstractType::Ptr to );

    //Used to store the count of steps by which a class needed to be converted to it's base-class
    int m_baseConversionLevels;
    const TopDUContext* m_topContext;
    TypeConversionCache* m_cache;
    friend class TypeConversionCacheEnabler;
};

///Use this to temporaily enable type-conversion caching
///@warning The duchain must not be locked while construction and destruction of this object!
class TypeConversionCacheEnabler {
public:

  TypeConversionCacheEnabler() {
    TypeConversion::startCache();
  }
  ~TypeConversionCacheEnabler() {
    TypeConversion::stopCache(); 
  }
};

}

#endif