2
Copyright 2007 David Nolden <david.nolden.kdevelop@art-master.de>
4
This library is free software; you can redistribute it and/or
5
modify it under the terms of the GNU Library General Public
6
License version 2 as published by the Free Software Foundation.
8
This library is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
Library General Public License for more details.
13
You should have received a copy of the GNU Library General Public License
14
along with this library; see the file COPYING.LIB. If not, write to
15
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16
Boston, MA 02110-1301, USA.
19
#include "expressionvisitor.h"
21
#include <language/duchain/duchainlock.h>
22
#include <language/duchain/duchain.h>
23
#include <parsesession.h>
24
#include <language/duchain/declaration.h>
25
#include <language/duchain/functiondefinition.h>
26
#include <language/duchain/types/identifiedtype.h>
28
#include <util/pushvalue.h>
30
#include "typebuilder.h"
32
#include <language/duchain/dumpchain.h>
33
#include "typeutils.h"
34
#include "name_visitor.h"
35
#include "type_visitor.h"
37
#include "overloadresolution.h"
38
#include "cppduchain.h"
39
#include "overloadresolutionhelper.h"
40
#include "builtinoperators.h"
41
#include "qtfunctiondeclaration.h"
42
#include "missingdeclarationtype.h"
43
#include "missingdeclarationproblem.h"
44
#include "dumpchain.h"
46
//If this is enabled and a type is not found, it is searched again with verbose debug output.
47
//#define DEBUG_RESOLUTION_PROBLEMS
49
//If this is enabled, all encounterd problems will be dumped to kDebug
50
// #define DUMP_PROBLEMS
52
//If this is enabled, problems will be created when no overloaded function was found for a function-call. This is expensive,
53
//because the problem report contains a lot of information, and the problem currently appears very often.
54
//#define DEBUG_FUNCTION_CALLS
56
const uint maxExpressionVisitorProblems = 400;
58
///Remember to always when visiting a node create a PushPositiveValue object for the context
60
/** A typical expression:
61
| | \ExpressionStatement[(39) (0, 92)] "d -> a = 5 ;"
62
| | | | \BinaryExpression[(39) (0, 92)] "d -> a = 5"
63
| | | | | \PostfixExpression[(39) (0, 92)] "d -> a"
64
| | | | | | \PrimaryExpression[(39) (0, 92)] "d"
65
| | | | | | | \Name[(39) (0, 92)] "d"
66
| | | | | | | | \UnqualifiedName[(39) (0, 92)] "d"
67
| | | | | | | | /UnqualifiedName[(40) (0, 93)]
68
| | | | | | | /Name[(40) (0, 93)]
69
| | | | | | /PrimaryExpression[(40) (0, 93)]
70
| | | | | | \ClassMemberAccess[(40) (0, 93)] "-> a"
71
| | | | | | | \Name[(41) (0, 95)] "a"
72
| | | | | | | | \UnqualifiedName[(41) (0, 95)] "a"
73
| | | | | | | | /UnqualifiedName[(42) (0, 97)]
74
| | | | | | | /Name[(42) (0, 97)]
75
| | | | | | /ClassMemberAccess[(42) (0, 97)]
76
| | | | | /PostfixExpression[(42) (0, 97)]
77
| | | | | \PrimaryExpression[(43) (0, 99)] "5"
78
| | | | | /PrimaryExpression[(44) (0, 100)]
79
| | | | /BinaryExpression[(44) (0, 100)]
80
| | | /ExpressionStatement[(45) (0, 102)
84
* @todo Deal DelayedType correctly everywhere.
85
* When a DelayedType is encountered, it should be filled with the
86
* appropriate expression to compute the type/value later on.
89
#define LOCKDUCHAIN DUChainReadLocker lock(DUChain::lock())
90
#define MUST_HAVE(X) if(!X) { problem( node, "no " # X ); return; }
93
using namespace KDevelop;
94
using namespace TypeUtils;
96
bool isNumber( const IndexedString& str ) {
97
static IndexedString _0("0");
98
static IndexedString _1("1");
99
static IndexedString _2("2");
100
static IndexedString _3("3");
101
static IndexedString _4("4");
102
static IndexedString _5("5");
103
static IndexedString _6("6");
104
static IndexedString _7("7");
105
static IndexedString _8("8");
106
static IndexedString _9("9");
109
return str == _0 || str == _1 || str == _2 || str == _3 || str == _4 || str == _5 || str == _6 || str == _7 || str == _8 || str == _9;
112
QHash<int, QString> initOperatorNames() {
113
QHash<int, QString> ret;
128
ret[Token_assign] = "=";
129
ret[Token_shift] = "<<"; ///@todo Parser does not differentiate between << and >>
130
ret[Token_eq] = "==";
131
ret[Token_not_eq] = "!=";
132
ret[Token_leq] = "<=";
133
ret[Token_geq] = ">=";
134
ret[Token_not_eq] = "!=";
135
ret[Token_and] = "&&";
136
ret[Token_or] = "||";
141
QHash<int, QString> operatorNames = initOperatorNames();
143
QString operatorNameFromTokenKind( int tokenKind )
145
QHash<int, QString>::const_iterator it = operatorNames.constFind(tokenKind);
146
if( it == operatorNames.constEnd() )
152
QList<DeclarationPointer> convert( const QList<Declaration*>& list ) {
153
QList<DeclarationPointer> ret;
154
foreach( Declaration* decl, list )
155
ret << DeclarationPointer(decl);
159
QList<Declaration*> convert( const QList<DeclarationPointer>& list ) {
160
QList<Declaration*> ret;
161
foreach( const DeclarationPointer &decl, list )
168
void ExpressionVisitor::visitIndependentNodes(const ListNode<_Tp> *nodes)
173
AbstractType::Ptr oldLastType = m_lastType;
174
Instance oldLastInstance = m_lastInstance;
177
*it = nodes->toFront(),
182
m_lastType = oldLastType;
183
m_lastInstance = oldLastInstance;
191
typedef PushPositiveValue<DUContext*> PushPositiveContext;
193
const Token& ExpressionVisitor::tokenFromIndex( int index ) {
194
return m_session->token_stream->token(index);
198
typedef PushValue<AbstractType::Ptr> PushAbstractType;
200
TopDUContext* ExpressionVisitor::topContext() const {
202
return const_cast<TopDUContext*>(m_source); ///@todo remove const_cast
208
bool ExpressionVisitor::isLValue( const AbstractType::Ptr& type, const Instance& instance ) {
209
return instance && (instance.declaration || isReferenceType(type));
212
ExpressionVisitor::ExpressionVisitor(ParseSession* session, const KDevelop::TopDUContext* source, bool strict) : m_strict(strict), m_memberAccess(false), m_skipLastNamePart(false), m_source(source), m_ignore_uses(0), m_session(session), m_currentContext(0), m_topContext(0), m_reportRealProblems(false) {
215
ExpressionVisitor::~ExpressionVisitor() {
218
QList<DeclarationPointer> ExpressionVisitor::lastDeclarations() const {
219
return m_lastDeclarations;
223
ParseSession* ExpressionVisitor::session() {
227
void ExpressionVisitor::parse( AST* ast ) {
229
m_lastInstance = Instance();
230
Q_ASSERT(ast->ducontext);
231
m_topContext = ast->ducontext->topContext();
237
void ExpressionVisitor::parseNamePrefix( NameAST* ast ) {
238
m_skipLastNamePart = true;
240
m_skipLastNamePart = false;
243
void ExpressionVisitor::reportRealProblems(bool report) {
244
m_reportRealProblems = report;
247
QList< KSharedPtr< KDevelop::Problem > > ExpressionVisitor::realProblems() const {
251
void ExpressionVisitor::problem( AST* node, const QString& str ) {
253
kDebug(9007) << "Cpp::ExpressionVisitor problem:" << str;
255
kDebug(9007) << "Cpp::ExpressionVisitor dumping the node that created the problem";
258
d.dump(node, m_session);
262
AbstractType::Ptr ExpressionVisitor::lastType() {
266
ExpressionVisitor::Instance ExpressionVisitor::lastInstance() {
267
return m_lastInstance;
270
/** Find the member in the declaration's du-chain. **/
271
void ExpressionVisitor::findMember( AST* node, AbstractType::Ptr base, const Identifier& member, bool isConst, bool postProblem ) {
275
PushPositiveContext pushContext( m_currentContext, node->ducontext );
279
base = realType(base, topContext(), &isConst);
283
isConst |= isConstant(base);
285
IdentifiedType* idType = dynamic_cast<IdentifiedType*>( base.unsafeData() );
286
//Make sure that it is a structure-type, because other types do not have members
287
StructureType* structureType = dynamic_cast<StructureType*>( base.unsafeData() );
289
if( !structureType || !idType ) {
290
problem( node, QString("findMember called on non-identified or non-structure type \"%1\"").arg(base ? base->toString() : "<type disappeared>") );
294
Declaration* declaration = idType->declaration(topContext());
295
MUST_HAVE(declaration);
296
MUST_HAVE(declaration->context());
298
DUContext* internalContext = declaration->logicalInternalContext(topContext());
300
MUST_HAVE( internalContext );
302
m_lastDeclarations = convert(findLocalDeclarations( internalContext, member, topContext() ));
305
if( m_lastDeclarations.isEmpty() ) {
307
problem( node, QString("could not find member \"%1\" in \"%2\", scope of context: %3").arg(member.toString()).arg(declaration->toString()).arg(declaration->context()->scopeIdentifier().toString()) );
312
//Give a default return without const-checking.
313
m_lastType = m_lastDeclarations.front()->abstractType();
314
m_lastInstance = Instance( m_lastDeclarations.front() );
316
//If it is a function, match the const qualifier
317
for( QList<DeclarationPointer>::const_iterator it = m_lastDeclarations.constBegin(); it != m_lastDeclarations.constEnd(); ++it ) {
318
AbstractType::Ptr t = (*it)->abstractType();
320
if( (t->modifiers() & AbstractType::ConstModifier) == isConst ) {
322
m_lastInstance.declaration = *it;
330
* Here the . and -> operators are implemented.
331
* Before visitClassMemberAccess is called, m_lastType and m_lastInstance must be set
337
void ExpressionVisitor::visitClassMemberAccess(ClassMemberAccessAST* node)
339
PushPositiveContext pushContext( m_currentContext, node->ducontext );
341
if( !m_lastInstance || !m_lastType ) {
342
problem(node, "VisitClassMemberAccess called without a base-declaration. '.' and '->' operators are only allowed on type-instances.");
346
bool isConst = false;
348
switch( tokenFromIndex(node->op).kind ) {
353
//When the type is a reference, dereference it so we get to the pointer-type
355
PointerType::Ptr pnt = realType(m_lastType, topContext()).cast<PointerType>();
357
/* kDebug(9007) << "got type:" << pnt->toString();
358
kDebug(9007) << "base-type:" << pnt->baseType()->toString();*/
360
isConst = isConstant(pnt.cast<AbstractType>());
361
//It is a pointer, reduce the pointer-depth by one
362
m_lastType = pnt->baseType();
363
m_lastInstance = Instance( getDeclaration(m_lastType) );
365
findMember( node, m_lastType, Identifier("operator->") );
367
problem( node, "no overloaded operator-> found" );
371
getReturnValue(node);
373
problem( node, "could not get return-type of operator->" );
377
if( !getPointerTarget(node, &isConst) ) {
382
if( !m_lastDeclarations.isEmpty() ) {
383
DeclarationPointer decl(m_lastDeclarations.first());
385
newUse( node, node->op, node->op+1, decl );
393
problem( node, QString("unknown class-member access operation: %1").arg( tokenFromIndex(node->op).kind ) );
398
m_memberAccess = true;
399
visitName(node->name);
400
m_memberAccess = false;
404
AbstractType::Ptr ExpressionVisitor::realLastType(bool* constant) const {
406
return AbstractType::Ptr(realType( m_lastType, topContext(), constant ));
409
bool ExpressionVisitor::getPointerTarget( AST* node, bool* constant ) {
410
if( !m_lastType ) return false;
412
AbstractType::Ptr base = realLastType();
416
PointerType* pnt = dynamic_cast<PointerType*>( base.unsafeData() );
419
(*constant) |= (pnt->modifiers() & AbstractType::ConstModifier);
420
m_lastType = pnt->baseType();
421
m_lastInstance = Instance(getDeclaration(m_lastType));
425
problem(node, QString("Cannot dereference base-type \"%1\"").arg(base->toString()) );
430
Declaration* ExpressionVisitor::getDeclaration( const AbstractType::Ptr& base ) {
431
if( !base ) return 0;
433
const IdentifiedType* idType = dynamic_cast<const IdentifiedType*>(base.unsafeData());
436
return idType->declaration(topContext());
443
* Here declarations are located
448
void ExpressionVisitor::visitName(NameAST* node)
450
PushPositiveContext pushContext( m_currentContext, node->ducontext );
452
DUContext* searchInContext = m_currentContext;
454
SimpleCursor position = m_session->positionAt( m_session->token_stream->position(node->start_token) );
455
if( m_currentContext->url() != m_session->m_url ) //.equals( m_session->m_url, KUrl::CompareWithoutTrailingSlash ) )
456
position = position.invalid();
458
if( m_memberAccess ) {
460
bool isConst = false; //@todo get this from upside
462
m_lastType = realType(m_lastType, topContext(), &isConst);
464
isConst |= isConstant(m_lastType);
466
IdentifiedType* idType = dynamic_cast<IdentifiedType*>( m_lastType.unsafeData() );
467
//Make sure that it is a structure-type, because other types do not have members
468
StructureType* structureType = dynamic_cast<StructureType*>( m_lastType.unsafeData() );
470
if( !structureType || !idType ) {
471
problem( node, QString("member searched in non-identified or non-structure type \"%1\"").arg(m_lastType ? m_lastType->toString() : "<type disappeared>") );
476
Declaration* declaration = idType->declaration(topContext());
477
MUST_HAVE(declaration);
478
MUST_HAVE(declaration->context());
480
searchInContext = declaration->logicalInternalContext(topContext());
482
MUST_HAVE( searchInContext );
487
NameASTVisitor nameV( m_session, this, searchInContext, topContext(), m_currentContext, position.isValid() ? position : searchInContext->range().end, m_memberAccess ? DUContext::DontSearchInParent : DUContext::NoSearchFlags );
488
nameV.run(node, m_skipLastNamePart);
490
if( nameV.identifier().isEmpty() ) {
491
problem( node, "name is empty" );
495
QualifiedIdentifier identifier = nameV.identifier();
497
///@todo It would be better if the parser would treat true and false exactly
498
///like constant-integer expressions, storing them in a primary expression.
499
static QualifiedIdentifier trueIdentifier("true");
500
static QualifiedIdentifier falseIdentifier("false");
502
if( identifier == trueIdentifier || identifier == falseIdentifier ) {
503
///We have a boolean constant, we need to catch that here
505
m_lastType = AbstractType::Ptr(new ConstantIntegralType(IntegralType::TypeBoolean));
506
m_lastInstance = Instance( true );
507
static_cast<ConstantIntegralType*>(m_lastType.unsafeData())->setValue<qint64>( identifier == trueIdentifier );
511
m_lastDeclarations = nameV.declarations();
513
if( m_lastDeclarations.isEmpty() || !m_lastDeclarations.first().data() ) {
515
if(Cpp::isTemplateDependent(m_currentContext) ) {
516
if(m_memberAccess || (node->qualified_names && nameV.foundSomething() && Cpp::isTemplateDependent(nameV.foundSomething().data()))) {
517
//Do nothing. Within a not instantiated template, we cannot be that sure
523
MissingDeclarationType::Ptr missing(new MissingDeclarationType);
525
missing->setIdentifier(IndexedTypeIdentifier(nameV.identifier()));
527
missing->containerContext = searchInContext;
529
missing->searchStartContext = m_currentContext;
531
if(m_reportRealProblems && m_problems.size() < maxExpressionVisitorProblems) {
532
KSharedPtr<KDevelop::Problem> problem(new Cpp::MissingDeclarationProblem(missing));
533
problem->setSource(KDevelop::ProblemData::SemanticAnalysis);
534
CppEditorIntegrator editor(session());
536
problem->setFinalLocation(DocumentRange(m_currentContext->url().str(), editor.findRange(node).textRange()));
537
if(!problem->range().isEmpty() && !editor.findRangeForContext(node->start_token, node->end_token).isEmpty())
538
m_problems << problem;
540
m_lastType = missing.cast<KDevelop::AbstractType>();
542
problem( node, QString("could not find declaration of %1").arg( nameV.identifier().toString() ) );
544
m_lastType = m_lastDeclarations.first()->abstractType();
545
//kDebug(9007) << "found declaration: " << m_lastDeclarations.first()->toString();
547
///If the found declaration declares a type, this is a type-expression and m_lastInstance should be zero.
548
///The declaration declares a type if its abstractType's declaration is that declaration. Else it is an insantiation, and m_lastType should be filled.
550
if( m_lastDeclarations.first()->kind() == Declaration::Instance )
551
m_lastInstance = Instance( m_lastDeclarations.first() );
553
m_lastInstance = Instance(false);
555
//A CppTemplateParameterType represents an unresolved template-parameter, so create a DelayedType instead.
556
if( dynamic_cast<CppTemplateParameterType*>(m_lastType.unsafeData()) )
557
createDelayedType(node, false);
561
expressionType( node, m_lastType, m_lastInstance );
565
/** Primary expressions just forward to their encapsulated expression
570
void ExpressionVisitor::visitPrimaryExpression(PrimaryExpressionAST* node)
572
PushPositiveContext pushContext( m_currentContext, node->ducontext );
576
if( node->literal ) {
577
visit( node->literal );
578
return; //We had a string-literal
581
if( !node->sub_expression && !node->expression_statement && !node->name )
583
IndexedString startNumber = IndexedString::fromIndex(m_session->contents()[tokenFromIndex(node->start_token).position]); //Extracts the first digit
585
if( isNumber(startNumber) )
588
for( size_t a = node->start_token; a < node->end_token; a++ )
589
num += tokenFromIndex(a).symbolString();
592
if( num.indexOf('.') != -1 || num.endsWith('f') || num.endsWith('d') ) {
595
while( !num.isEmpty() && !ok ) {
596
val = num.toDouble(&ok);
597
num.truncate(num.length()-1);
601
if( num.endsWith('f') ) {
602
m_lastType = AbstractType::Ptr(new ConstantIntegralType(IntegralType::TypeFloat));
603
static_cast<ConstantIntegralType*>(m_lastType.unsafeData())->setValue<float>((float)val);
605
m_lastType = AbstractType::Ptr(new ConstantIntegralType(IntegralType::TypeDouble));
606
static_cast<ConstantIntegralType*>(m_lastType.unsafeData())->setValue<double>(val);
610
uint mod = AbstractType::NoModifiers;
612
if( num.endsWith("u") || ( num.length() > 1 && num[1] == 'x' ) )
613
mod = AbstractType::UnsignedModifier;
616
while( !num.isEmpty() && !ok ) {
617
val = num.toLongLong(&ok, 0);
618
num.truncate(num.length()-1);
621
m_lastType = AbstractType::Ptr(new ConstantIntegralType(IntegralType::TypeInt));
622
m_lastType->setModifiers(mod);
624
if( mod & AbstractType::UnsignedModifier )
625
ConstantIntegralType::Ptr::staticCast(m_lastType)->setValue<quint64>(val);
627
ConstantIntegralType::Ptr::staticCast(m_lastType)->setValue<qint64>(val);
629
m_lastInstance = Instance(true);
635
visit( node->sub_expression );
636
visit( node->expression_statement );
639
const Token& token(tokenFromIndex(node->token));
641
static const IndexedString True("true");
642
static const IndexedString False("false");
644
if(token.kind == Token_char_literal) {
645
// char literal e.g. 'x'
647
m_lastType = AbstractType::Ptr(new ConstantIntegralType(IntegralType::TypeChar));
648
m_lastInstance = Instance( true );
649
if ( token.size == 3 ) {
650
static_cast<ConstantIntegralType*>(m_lastType.unsafeData())->setValue<char>( token.symbolByteArray().at(1) );
651
} else if (token.size == 4) {
652
if (token.symbolByteArray() == "'\\t'") {
653
static_cast<ConstantIntegralType*>(m_lastType.unsafeData())->setValue<char>('\t');
654
} else if (token.symbolByteArray() == "'\\n'") {
655
static_cast<ConstantIntegralType*>(m_lastType.unsafeData())->setValue<char>('\n');
656
} else if (token.symbolByteArray() == "'\\r'") {
657
static_cast<ConstantIntegralType*>(m_lastType.unsafeData())->setValue<char>('\r');
661
} else if(token.symbol() == True || token.symbol() == False) {
662
///We have a boolean constant, we need to catch that here
664
m_lastType = AbstractType::Ptr(new ConstantIntegralType(IntegralType::TypeBoolean));
665
m_lastInstance = Instance( true );
666
static_cast<ConstantIntegralType*>(m_lastType.unsafeData())->setValue<qint64>( token.symbol() == True );
669
//Respect "this" token
670
if( token.kind == Token_this ) {
673
AbstractType::Ptr thisType;
675
DUContext* context = m_currentContext; //Here we find the context of the function-declaration/definition we're currently in
676
while( context->parentContext() && context->type() == DUContext::Other && context->parentContext()->type() == DUContext::Other )
677
{ //Move context to the top context of type "Other". This is needed because every compound-statement creates a new sub-context.
678
context = context->parentContext();
681
///Step 1: Find the function-declaration for the function we are in
682
Declaration* functionDeclaration = 0;
684
if( context->owner() && dynamic_cast<FunctionDefinition*>(context->owner()) )
685
functionDeclaration = static_cast<FunctionDefinition*>(context->owner())->declaration(topContext());
687
if( !functionDeclaration && context->owner() )
688
functionDeclaration = context->owner();
690
if( !functionDeclaration )
692
problem(node, "\"this\" used, but no function-declaration could be found");
696
///Step 2: Find the type of "this" from the function-declaration
697
DUContext* classContext = functionDeclaration->context();
699
//Take the type from the classContext
700
if( classContext && classContext->type() == DUContext::Class && classContext->owner() && classContext->owner() )
701
thisType = classContext->owner()->abstractType();
704
problem(node, "\"this\" used in invalid classContext");
708
///Step 3: Create a pointer-type for the "this" type and return it
709
KDevelop::FunctionType::Ptr cppFunction = functionDeclaration->abstractType().cast<KDevelop::FunctionType>();
712
PointerType::Ptr thisPointer( new PointerType() );
713
thisPointer->setModifiers(cppFunction->modifiers() & (AbstractType::ConstModifier | AbstractType::VolatileModifier));
714
thisPointer->setBaseType( thisType );
716
m_lastType = thisPointer.cast<AbstractType>();
717
m_lastInstance = Instance(true);
719
if( context->owner() && context->owner() && context->owner()->abstractType() )
720
problem(node, QString("\"this\" used in non-function context of type %1(%2)").arg( "unknown" ) .arg(m_currentContext->owner()->abstractType()->toString()));
722
problem(node, "\"this\" used in non-function context with invalid type");
727
expressionType( node, m_lastType, m_lastInstance );
730
/** Translation-units just forward to their encapsulated expression */
731
void ExpressionVisitor::visitTranslationUnit(TranslationUnitAST* node)
733
PushPositiveContext pushContext( m_currentContext, node->ducontext );
735
visitNodes(this, node->declarations);
738
expressionType( node, m_lastType, m_lastInstance );
741
/** Sub-expressions of a post-fix expression, will be applied in order to m_lastType
745
void ExpressionVisitor::visitSubExpressions( AST* node, const ListNode<ExpressionAST*>* nodes ) {
748
PushPositiveContext pushContext( m_currentContext, node->ducontext );
750
bool onlyFunctionCalls = false;
753
problem( node, "primary expression returned no type" );
754
onlyFunctionCalls = true; //We want to visit function-calls even when the function was not resolved, so we get uses for the arguments
756
const ListNode<ExpressionAST*> *it = nodes->toFront(), *end = it;
761
if( !onlyFunctionCalls || (it->element && it->element->kind == AST::Kind_FunctionCall) )
765
problem( node, QString("while parsing post-fix-expression: sub-expression %1 returned no type").arg(num) );
774
expressionType( node, m_lastType, m_lastInstance );
777
/** A postfix-expression is a primary expression together with a chain of sub-expressions that are applied from left to right
781
void ExpressionVisitor::visitPostfixExpression(PostfixExpressionAST* node)
783
PushPositiveContext pushContext( m_currentContext, node->ducontext );
786
if( node->type_specifier ) {
787
problem( node, "unexpected type-specifier" );
790
if( !node->expression ) {
791
problem( node, "primary expression missing" );
794
//First evaluate the primary expression, and then pass the result from sub-expression to sub-expression through m_lastType
795
visit( node->expression );
797
if( !node->sub_expressions )
800
visitSubExpressions( node, node->sub_expressions );
803
/** A helper-class for evaluating constant unary expressions under different types(int, float, etc.) */
805
struct ConstantUnaryExpressionEvaluator {
813
* Writes the results into endValue, type, and modifier.
815
ConstantUnaryExpressionEvaluator( int tokenKind, ConstantIntegralType* left ) {
817
type = left->dataType();
818
modifier = left->modifiers();
819
evaluateSpecialTokens( tokenKind, left );
820
switch( tokenKind ) {
822
endValue = +left->value<Type>();
825
endValue = -left->value<Type>();
828
endValue = left->value<Type>()+1;
830
endValue = left->value<Type>()-1;
834
//This function is used to disable some operators on bool and double values
835
void evaluateSpecialTokens( int tokenKind, ConstantIntegralType* left ) {
836
switch( tokenKind ) {
838
endValue = ~left->value<Type>();
841
endValue = !left->value<Type>();
846
AbstractType::Ptr createType() {
847
AbstractType::Ptr ret = AbstractType::Ptr(new ConstantIntegralType(type));
848
ret->setModifiers(modifier);
849
static_cast<ConstantIntegralType*>(ret.unsafeData())->setValue<Type>( endValue );
855
void ConstantUnaryExpressionEvaluator<double>::evaluateSpecialTokens( int tokenKind, ConstantIntegralType* left ) {
861
void ConstantUnaryExpressionEvaluator<float>::evaluateSpecialTokens( int tokenKind, ConstantIntegralType* left ) {
866
QString toString(AbstractType::Ptr t) {
869
return t->toString();
872
void ExpressionVisitor::createDelayedType( AST* node , bool expression ) {
873
DelayedType::Ptr type(new DelayedType());
875
for( size_t s = node->start_token; s < node->end_token; ++s )
876
id += m_session->token_stream->token(s).symbolString();
878
//We have to prevent automatic parsing and splitting by QualifiedIdentifier and Identifier
880
idd.setIdentifier(id);
882
QualifiedIdentifier ident;
885
ident.setIsExpression( expression );
886
type->setIdentifier( IndexedTypeIdentifier(ident) );
887
m_lastType = type.cast<AbstractType>();
892
* partially have test **/
893
void ExpressionVisitor::visitBinaryExpression(BinaryExpressionAST* node) {
894
PushPositiveContext pushContext( m_currentContext, node->ducontext );
898
///First resolve left part, then right, then combine
899
visit(node->left_expression);
901
Instance leftInstance = m_lastInstance;
902
AbstractType::Ptr leftType = m_lastType;
905
if( tokenFromIndex(node->op).kind == ',' ) {
906
/**A ',' binary expression is used for separating the argument-expressions in a function-call.
907
* Those should be collected into m_parameters
909
* How this should work: Every binary ',' expression yields a m_lastType of null.
911
* So whenever an operand(left or right side) yields a type, we can be sure it is not a binary-expression
912
* so we can add the type to the parameter-list.
914
if( leftType && leftInstance) {
915
m_parameters << OverloadResolver::Parameter(leftType, isLValue( leftType, leftInstance ) );
916
m_parameterNodes.append(node->left_expression);
919
//kDebug(9007) << "Adding parameter from left: " << (leftType.data() ? leftType->toString() : QString("<notype>"));
921
//If neither leftType nor leftInstance are true, the expression was probably another binary
922
//expression that has put the types/instances into m_parameters and returns nothing.
923
if( leftType || leftInstance ) {
925
problem( node->left_expression, "left operand of binary ','-expression is no type-instance" );
927
problem( node->left_expression, "left operand of binary ','-expression could not be evaluated" );
929
m_parameters << OverloadResolver::Parameter(AbstractType::Ptr(), false);
930
m_parameterNodes.append(node->left_expression);
932
//kDebug(9007) << "Adding empty from left";
937
visit(node->right_expression);
939
Instance rightInstance = m_lastInstance;
940
AbstractType::Ptr rightType = m_lastType;
943
if( tokenFromIndex(node->op).kind == ',' ) {
945
if( rightType && rightInstance) {
946
m_parameters << OverloadResolver::Parameter(rightType, isLValue( rightType, rightInstance ) );
947
m_parameterNodes.append(node->right_expression);
949
//kDebug(9007) << "Adding parameter from right: " << (rightType.data() ? rightType->toString() : QString("<notype>"));
951
//If neither leftType nor leftInstance are true, the expression was probably another binary
952
//expression that has put the types/instances into m_parameters and returns nothing.
953
if( rightType || rightInstance ) {
955
problem( node->right_expression, "right operand of binary ','-expression is no type-instance" );
957
problem( node->right_expression, "right operand of binary ','-expression could not be evaluated" );
959
m_parameters << OverloadResolver::Parameter(AbstractType::Ptr(), false);
960
m_parameterNodes.append(node->right_expression);
961
//kDebug(9007) << "Adding empty from right";
969
if(MissingDeclarationType::Ptr missing = leftType.cast<Cpp::MissingDeclarationType>()) {
971
Cpp::ExpressionEvaluationResult res;
972
res.type = rightType->indexed();
973
res.isInstance = rightInstance;
974
missing->assigned = res;
980
if(MissingDeclarationType::Ptr missing = rightType.cast<Cpp::MissingDeclarationType>()) {
982
Cpp::ExpressionEvaluationResult res;
983
res.type = leftType->indexed();
984
res.isInstance = leftInstance;
985
missing->convertedTo = res;
991
if( !leftInstance && !leftType ) {
992
problem( node, "left operand of binary expression could not be evaluated" );
996
if( !rightInstance && !rightType ) {
997
problem( node, "right operand of binary expression could not be evaluated" );
998
m_lastInstance = leftInstance;
999
m_lastType = leftType;
1003
if( dynamic_cast<DelayedType*>(rightType.unsafeData()) || dynamic_cast<DelayedType*>(leftType.unsafeData()) ) {
1004
m_lastInstance = Instance(true);
1005
createDelayedType(node);
1009
int tokenKind = tokenFromIndex(node->op).kind;
1011
if(rightType && leftType && rightInstance && leftInstance) {
1013
//Test if there is a builtin operator that can be used. If it is, this will also evaluate the values of constant expressions.
1014
m_lastType = binaryOperatorReturnType(leftType, rightType, tokenKind);
1015
m_lastInstance = Instance(true);
1018
QString op = operatorNameFromTokenKind(tokenFromIndex(node->op).kind);
1020
bool success = false;
1024
KDevelop::DUContextPointer ptr(m_currentContext);
1025
OverloadResolutionHelper helper(ptr, TopDUContextPointer(topContext()) );
1026
helper.setOperator( OverloadResolver::Parameter(leftType, isLValue( leftType, leftInstance ) ), op );
1027
helper.setKnownParameters( OverloadResolver::ParameterList( OverloadResolver::Parameter(rightType, isLValue( rightType, rightInstance ) ) ) );
1028
QList<OverloadResolutionFunction> functions = helper.resolve(false);
1030
if( !functions.isEmpty() )
1032
KDevelop::FunctionType::Ptr function = functions.first().function.declaration()->type<KDevelop::FunctionType>();
1033
if( functions.first().function.isViable() && function ) {
1035
m_lastType = function->returnType();
1036
m_lastInstance = Instance(functions.first().function.declaration());
1039
newUse( node, node->op, node->op+1, functions.first().function.declaration() );
1041
//Do not complain here, because we do not check for builtin operators
1042
//problem(node, "No fitting operator. found" );
1043
//problem(node, QString("Found no viable operator-function"));
1046
//Do not complain here, because we do not check for builtin operators
1047
//problem(node, "No fitting operator. found" );
1049
//Find an overloaded binary operator
1051
problem(node, "not implemented binary expression" );
1055
m_lastType = leftType;
1056
m_lastInstance = leftInstance;
1062
expressionType( node, m_lastType, m_lastInstance );
1069
void ExpressionVisitor::visitTypeSpecifier(TypeSpecifierAST* ast)
1071
PushPositiveContext pushContext( m_currentContext, ast->ducontext );
1075
TypeASTVisitor comp(m_session, this, m_currentContext, topContext(), m_currentContext);
1080
QList<DeclarationPointer> decls = comp.declarations();
1082
m_lastType = comp.type();
1084
if( !decls.isEmpty() )
1086
m_lastDeclarations = decls;
1087
// m_lastType = decls.first()->abstractType(); If we do this, we may lose modifiers and such
1089
if( decls.first()->kind() == Declaration::Type )
1090
m_lastInstance = Instance(false);
1092
///Allow non-types, because we sometimes don't know whether something is a type or not, and it may get parsed as a type.
1093
m_lastInstance = Instance(decls.first());
1095
if( dynamic_cast<CppTemplateParameterType*>(m_lastType.unsafeData()) )
1096
createDelayedType(ast, false);
1098
problem(ast, "Could not resolve type");
1099
#ifdef DEBUG_RESOLUTION_PROBLEMS
1100
//Run the ast-visitor in debug mode
1103
TypeASTVisitor comp2(m_session, this, m_currentContext, topContext(), true);
1110
void ExpressionVisitor::visitSimpleTypeSpecifier(SimpleTypeSpecifierAST* node)
1112
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1115
TypeASTVisitor tvisitor(m_session, this, m_currentContext, topContext(), m_currentContext);
1117
m_lastType = tvisitor.type();
1118
m_lastDeclarations = tvisitor.declarations();
1119
m_lastInstance = Instance(false);
1122
void ExpressionVisitor::visitInitDeclarator(InitDeclaratorAST* node)
1124
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1126
if(node->declarator)
1128
CppClassType::Ptr constructedType = computeConstructedType();
1130
//Build constructor uses (similar to visitFunctionCall)
1132
AbstractType::Ptr oldLastType = m_lastType;
1133
Instance oldInstance = m_lastInstance;
1134
QList< DeclarationPointer > declarations = m_lastDeclarations;
1140
size_t token = node->start_token;
1142
if(node->initializer)
1144
if(node->initializer->expression && !node->initializer->initializer_clause)
1146
token = node->initializer->start_token;
1147
fail = !buildParametersFromExpression(node->initializer->expression);
1148
} else if(!node->initializer->expression && node->initializer->initializer_clause && constructedType)
1149
{ // report operator= use in i.e.: foo = bar;
1150
token = node->initializer->start_token;
1151
fail = !buildParametersFromExpression(node->initializer->initializer_clause->expression);
1153
declarations.clear();
1154
if ( ClassDeclaration* cdec = dynamic_cast<ClassDeclaration*>(constructedType->declaration(m_source)) ) {
1155
///TODO: global operator= functions, for now only class members are handled
1156
foreach(Declaration* dec, cdec->internalContext()->findDeclarations(Identifier("operator="))) {
1157
declarations << DeclarationPointer(dec);
1162
else if(node->declarator->parameter_is_initializer && node->declarator->parameter_declaration_clause)
1164
token = node->declarator->parameter_declaration_clause->start_token-1;
1165
fail = !buildParametersFromDeclaration(node->declarator->parameter_declaration_clause);
1168
if(fail || !constructedType) {
1169
DefaultVisitor::visitInitDeclarator(node);
1173
DeclarationPointer chosenFunction;
1177
KDevelop::DUContextPointer ptr(m_currentContext);
1178
OverloadResolver resolver( ptr, KDevelop::TopDUContextPointer(topContext()), oldInstance );
1181
chosenFunction = resolver.resolveList(m_parameters, convert(declarations));
1182
else if(!declarations.isEmpty() && !m_strict)
1183
chosenFunction = declarations.first();
1187
newUse( node , token, token+1, chosenFunction );
1189
DefaultVisitor::visitInitDeclarator(node);
1193
//Used to parse pointer-depth and cv-qualifies of types in new-expessions and casts
1194
void ExpressionVisitor::visitDeclarator(DeclaratorAST* node) {
1195
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1198
problem(node, "Declarator used without type");
1202
if( m_lastInstance ) {
1203
problem(node, "Declarator used on an instance instead of a type");
1208
AbstractType::Ptr oldLastType = m_lastType;
1209
Instance oldLastInstance = m_lastInstance;
1211
visit(node->sub_declarator);
1213
visit(node->bit_expression);
1214
visitNodes(this, node->array_dimensions);
1216
visit(node->parameter_declaration_clause);
1217
visit(node->exception_spec);
1220
if( node->array_dimensions && oldLastType ) {
1221
ArrayType::Ptr p( new ArrayType() );
1222
p->setElementType( oldLastType );
1224
m_lastType = p.cast<AbstractType>();
1225
m_lastInstance = Instance(false);
1227
m_lastType = oldLastType;
1228
m_lastInstance = oldLastInstance;
1231
visitNodes(this, node->ptr_ops);
1234
void ExpressionVisitor::visitNewDeclarator(NewDeclaratorAST* node) {
1235
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1238
problem(node, "Declarator used without type");
1242
if( m_lastInstance ) {
1243
problem(node, "Declarator used on an instance instead of a type");
1247
AbstractType::Ptr lastType = m_lastType;
1248
Instance instance = m_lastInstance;
1250
DefaultVisitor::visitNewDeclarator(node);
1252
m_lastType = lastType;
1253
m_lastInstance = instance;
1256
visit(node->ptr_op);
1259
void ExpressionVisitor::visitCppCastExpression(CppCastExpressionAST* node) {
1261
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1263
//Visit the expression just so it is evaluated and expressionType(..) eventually called, the result will not be used here
1265
visit( node->expression );
1269
visit(node->type_id);
1272
problem(node, "Could not resolve type");
1276
m_lastInstance = Instance(true);
1279
expressionType( node, m_lastType, m_lastInstance );
1281
visitSubExpressions( node, node->sub_expressions );
1283
//Used to parse pointer-depth and cv-qualifies of types in new-expessions and casts
1284
void ExpressionVisitor::visitPtrOperator(PtrOperatorAST* node) {
1285
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1288
problem(node, "Pointer-operator used without type");
1292
if( m_lastInstance ) {
1293
problem(node, "Pointer-operator used on an instance instead of a type");
1299
static IndexedString ref("&");
1300
static IndexedString ptr("*");
1302
IndexedString op = m_session->token_stream->token(node->op).symbol();
1307
PointerType::Ptr p( new PointerType() );
1308
p->setBaseType( m_lastType );
1309
p->setModifiers(TypeBuilder::parseConstVolatile(m_session, node->cv));
1311
m_lastType = p.cast<AbstractType>();
1313
ReferenceType::Ptr p( new ReferenceType() );
1314
p->setBaseType( m_lastType );
1315
p->setModifiers(TypeBuilder::parseConstVolatile(m_session, node->cv));
1317
m_lastType = p.cast<AbstractType>();
1319
m_lastInstance = Instance(false);
1325
void ExpressionVisitor::visitCastExpression(CastExpressionAST* node) {
1327
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1329
//Visit the expression just so it is evaluated and expressionType(..) eventually called, the result will not be used here
1332
visit( node->expression );
1336
//Visit declarator and type-specifier, which should build the type
1337
if( node->type_id ) {
1338
visit(node->type_id->type_specifier);
1339
visit(node->type_id->declarator);
1342
problem(node, "Could not resolve type");
1346
m_lastInstance = Instance(true);
1349
expressionType( node, m_lastType, m_lastInstance );
1352
void ExpressionVisitor::visitNewExpression(NewExpressionAST* node) {
1353
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1355
visit( node->expression );
1358
CppClassType::Ptr constructedType;
1361
//Visit declarator and type-specifier, which should build the type
1362
if( node->type_id ) {
1363
visit(node->type_id->type_specifier);
1364
constructedType = computeConstructedType();
1365
visit(node->type_id->declarator);
1366
} else if( node->new_type_id ) {
1367
visit(node->new_type_id->type_specifier);
1368
constructedType = computeConstructedType();
1369
visit(node->new_type_id->new_declarator);
1375
///@todo cv-qualifiers
1376
PointerType::Ptr p( new PointerType() );
1377
p->setBaseType( m_lastType );
1379
m_lastType = p.cast<AbstractType>();
1381
m_lastInstance = Instance(true);
1384
expressionType( node, m_lastType, m_lastInstance );
1386
problem(node, "Could not resolve type");
1389
AbstractType::Ptr lastType = m_lastType;
1390
Instance instance = m_lastInstance;
1392
if(node->new_initializer) {
1394
//Build constructor uses (similar to visitFunctionCall)
1395
//Largely a copy of visitInitDeclarator()
1397
AbstractType::Ptr oldLastType = m_lastType;
1398
Instance oldInstance = m_lastInstance;
1399
QList< DeclarationPointer > declarations = m_lastDeclarations;
1403
bool fail = !buildParametersFromExpression(node->new_initializer->expression);
1405
size_t token = node->new_initializer->start_token;
1407
DeclarationPointer chosenFunction;
1411
KDevelop::DUContextPointer ptr(m_currentContext);
1412
OverloadResolver resolver( ptr, KDevelop::TopDUContextPointer(topContext()), oldInstance );
1415
chosenFunction = resolver.resolveList(m_parameters, convert(declarations));
1416
else if(!declarations.isEmpty() && !m_strict)
1417
chosenFunction = declarations.first();
1421
newUse( node , token, token+1, chosenFunction );
1424
m_lastType = lastType;
1425
m_lastInstance = instance;
1431
void ExpressionVisitor::visitConditionalExpression(ConditionalExpressionAST* node)
1433
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1435
//Also visit the not interesting parts, so they are evaluated
1438
visit(node->condition);
1441
if( dynamic_cast<DelayedType*>(m_lastType.unsafeData()) ) {
1442
//Store the expression so it's evaluated later
1443
m_lastInstance = Instance(true);
1444
createDelayedType(node);
1448
AbstractType::Ptr conditionType = m_lastType;
1451
visit(node->left_expression);
1452
AbstractType::Ptr leftType = m_lastType;
1456
///@todo test if result of right expression can be converted to the result of the right expression. If not, post a problem(because c++ wants it that way)
1458
//Since both possible results of a conditional expression must have the same type, we only consider the right one here
1459
visit(node->right_expression);
1463
if( ConstantIntegralType* condition = dynamic_cast<ConstantIntegralType*>( conditionType.unsafeData() ) ) {
1464
///For constant integral types, the condition could be evaluated, so we choose the correct result.
1465
if( condition->value<quint64>() == 0 ) {
1466
///The right expression is the correct one, so do nothing
1468
///Condition is true, so we choose the left expression value/type
1469
m_lastType = leftType;
1476
expressionType( node, m_lastType, m_lastInstance );
1481
void ExpressionVisitor::visitExpressionStatement(ExpressionStatementAST* node)
1483
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1485
visit(node->expression);
1487
expressionType( node, m_lastType, m_lastInstance );
1490
/** For a compound statement, process all statements and return the type of the last one
1493
void ExpressionVisitor::visitCompoundStatement(CompoundStatementAST* node)
1495
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1496
visitIndependentNodes(node->statements);
1502
void ExpressionVisitor::visitExpressionOrDeclarationStatement(ExpressionOrDeclarationStatementAST* node) {
1503
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1504
//visit(node->declaration);
1505
visit(node->expression);
1508
expressionType( node, m_lastType, m_lastInstance );
1511
bool ExpressionVisitor::dereferenceLastPointer(AST* node) {
1512
if( PointerType::Ptr pt = realLastType().cast<PointerType>() )
1515
m_lastType = pt->baseType();
1516
m_lastInstance = Instance( getDeclaration(m_lastType) );
1518
}else if( ArrayType::Ptr pt = realLastType().cast<ArrayType>() ) {
1519
m_lastType = pt->elementType();
1520
m_lastInstance = Instance( getDeclaration(m_lastType) );
1528
* partially have test */
1529
void ExpressionVisitor::visitUnaryExpression(UnaryExpressionAST* node)
1531
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1535
visit(node->expression);
1537
if( !m_lastInstance || !m_lastType ) {
1539
problem(node, "Tried to evaluate unary expression on a non-instance item" );
1543
if( m_lastType.cast<DelayedType>() ) {
1544
//Store the expression so it's evaluated later
1545
m_lastInstance = Instance(true);
1546
createDelayedType(node);
1550
switch( tokenFromIndex(node->op).kind ) {
1554
if( dereferenceLastPointer(node) ) {
1556
//Get return-value of operator*
1557
findMember(node, m_lastType, Identifier("operator*") );
1559
problem( node, "no overloaded operator* found" );
1563
getReturnValue(node);
1565
if( !m_lastDeclarations.isEmpty() ) {
1566
DeclarationPointer decl( m_lastDeclarations.first() );
1568
newUse( node, node->op, node->op+1, decl );
1575
m_lastType = increasePointerDepth(m_lastType);
1576
//m_lastInstance will be left alone as it was before. A pointer is not identified, and has no declaration.
1581
KDevelop::IntegralType* integral = dynamic_cast<KDevelop::IntegralType*>(m_lastType.unsafeData());
1583
//The type of integral types does not change on unary operators
1584
//Eventually evaluate the value of constant integral types
1585
ConstantIntegralType* constantIntegral = dynamic_cast<ConstantIntegralType*>(integral);
1587
if( constantIntegral ) {
1589
switch( constantIntegral->dataType() ) {
1590
case IntegralType::TypeFloat:
1592
ConstantUnaryExpressionEvaluator<float> evaluator( tokenFromIndex(node->op).kind, constantIntegral );
1593
m_lastType = evaluator.createType();
1596
case IntegralType::TypeDouble:
1598
ConstantUnaryExpressionEvaluator<double> evaluator( tokenFromIndex(node->op).kind, constantIntegral );
1599
m_lastType = evaluator.createType();
1603
if( constantIntegral->modifiers() & AbstractType::UnsignedModifier ) {
1604
ConstantUnaryExpressionEvaluator<quint64> evaluator( tokenFromIndex(node->op).kind, constantIntegral );
1605
m_lastType = evaluator.createType();
1607
ConstantUnaryExpressionEvaluator<qint64> evaluator( tokenFromIndex(node->op).kind, constantIntegral );
1608
m_lastType = evaluator.createType();
1613
m_lastInstance = Instance(true);
1616
QString op = operatorNameFromTokenKind(tokenFromIndex(node->op).kind);
1620
KDevelop::DUContextPointer ptr(m_currentContext);
1621
OverloadResolutionHelper helper( ptr, TopDUContextPointer(topContext()) );
1622
helper.setOperator( OverloadResolver::Parameter(m_lastType, isLValue( m_lastType, m_lastInstance ) ), op );
1624
//helper.setKnownParameters( OverloadResolver::Parameter(rightType, isLValue( rightType, rightInstance ) ) );
1625
QList<OverloadResolutionFunction> functions = helper.resolve(false);
1627
if( !functions.isEmpty() )
1629
KDevelop::FunctionType::Ptr function = functions.first().function.declaration()->type<KDevelop::FunctionType>();
1630
if( functions.first().function.isViable() && function ) {
1631
m_lastType = function->returnType();
1632
m_lastInstance = Instance(true);
1635
newUse( node, node->op, node->op+1, functions.first().function.declaration() );
1637
problem(node, QString("Found no viable function"));
1640
//Do not complain here, because we do not check for builtin operators
1641
//problem(node, "No fitting operator. found" );
1645
problem(node, "Invalid unary expression");
1653
expressionType( node, m_lastType, m_lastInstance );
1656
void ExpressionVisitor::getReturnValue( AST* node ) {
1660
KDevelop::FunctionType* f = dynamic_cast<KDevelop::FunctionType*>( m_lastType.unsafeData() );
1663
problem(node, QString("cannot get return-type of type %1, it is not a function-type").arg(m_lastType->toString()));
1665
m_lastInstance = Instance();
1669
m_lastType = f->returnType();
1670
//Just keep the function instance, set in findMember(..)
1674
CppClassType::Ptr ExpressionVisitor::computeConstructedType()
1676
CppClassType::Ptr constructedType;
1678
AbstractType::Ptr oldLastType = m_lastType;
1680
if(!m_lastInstance) {
1682
if(m_lastDeclarations.isEmpty() && m_lastType && !m_lastInstance) {
1683
IdentifiedType* idType = dynamic_cast<IdentifiedType*>(m_lastType.unsafeData());
1685
Declaration* decl = idType->declaration(m_source);
1687
m_lastDeclarations << DeclarationPointer(decl);
1691
if( !m_lastDeclarations.isEmpty() && m_lastDeclarations.first().data() && m_lastDeclarations.first()->kind() == Declaration::Type && (constructedType = unAliasedType(m_lastDeclarations.first()->logicalDeclaration(topContext())->abstractType()).cast<CppClassType>()) ) {
1693
if( constructedType && constructedType->declaration(topContext()) && constructedType->declaration(topContext())->internalContext() )
1695
Declaration* constructedDecl = constructedType->declaration(topContext());
1697
//Replace a type with its constructros if there is constructors available, so overload-resolution can happen
1698
m_lastDeclarations = convert(constructedDecl->internalContext()->findLocalDeclarations( constructedDecl->identifier(), constructedDecl->internalContext()->range().end, topContext(), AbstractType::Ptr(), DUContext::OnlyFunctions ));
1703
return constructedType;
1706
bool ExpressionVisitor::buildParametersFromDeclaration(ParameterDeclarationClauseAST* node, bool store)
1709
m_parameters.clear();
1710
m_parameterNodes.clear();
1713
if(node->parameter_declarations)
1715
const ListNode<ParameterDeclarationAST*>
1716
*it = node->parameter_declarations->toFront(),
1721
//Just to make sure we build the uses. This problem only appears if we mis-parse a declarator as a parameter declaration
1722
if(it->element->declarator && it->element->declarator->array_dimensions)
1724
const ListNode< ExpressionAST* >* itt = it->element->declarator->array_dimensions->toFront(), *end2 = itt;
1726
visit(it->element->declarator->array_dimensions->element);
1727
}while(itt != end2);
1730
visit(it->element->type_specifier);
1732
if(it->element->declarator) {
1733
///@todo Eventually build constructor uses for mis-parsed sub-declarators or parameter-declaration-clauses
1734
if(it->element->declarator->sub_declarator && it->element->declarator->sub_declarator->id)
1736
//Special handling is required: Things that really are initializers are treated as declarators in a mis-parsed ParameterDeclarationClause
1737
visitName(it->element->declarator->sub_declarator->id);
1738
}else if(it->element->declarator->parameter_declaration_clause)
1740
buildParametersFromDeclaration(it->element->declarator->parameter_declaration_clause, false);
1743
visit(it->element->expression);
1745
m_parameters.append( OverloadResolver::Parameter( m_lastType, isLValue( m_lastType, m_lastInstance ) ) );
1746
m_parameterNodes.append(it->element);
1756
//Check if all parameters could be evaluated
1758
for( QList<OverloadResolver::Parameter>::const_iterator it = m_parameters.constBegin(); it != m_parameters.constEnd(); ++it ) {
1760
problem( node, QString("parameter %1 could not be evaluated").arg(paramNum) );
1770
bool ExpressionVisitor::buildParametersFromExpression(AST* expression)
1773
* Evaluate the function-argument types. Those are represented a little strangely:
1774
* expression contains them, using recursive binary expressions
1777
m_parameters.clear();
1778
m_parameterNodes.clear();
1785
//binary expressions don't yield m_lastType, so when m_lastType is set wo probably only have one single parameter
1787
m_parameters << OverloadResolver::Parameter( m_lastType, isLValue( m_lastType, m_lastInstance ) );
1788
m_parameterNodes.append(expression);
1791
//Check if all parameters could be evaluated
1794
for( QList<OverloadResolver::Parameter>::const_iterator it = m_parameters.constBegin(); it != m_parameters.constEnd(); ++it ) {
1796
problem( expression, QString("parameter %1 could not be evaluated").arg(paramNum) );
1805
void ExpressionVisitor::visitFunctionCall(FunctionCallAST* node) {
1806
PushPositiveContext pushContext( m_currentContext, node->ducontext );
1809
* If a class name was found, get its constructors.
1811
AbstractType::Ptr oldLastType = m_lastType;
1813
CppClassType::Ptr constructedType;
1815
if(!m_lastInstance) {
1816
constructedType = computeConstructedType();
1818
if(m_lastDeclarations.isEmpty() && m_lastType) {
1820
//The function-call operator may also be applied on instances that don't have an explicit declaration, like return-values
1821
AbstractType::Ptr type = realType(m_lastType);
1822
IdentifiedType* identified = dynamic_cast<IdentifiedType*>(type.unsafeData());
1824
DeclarationPointer decl(identified->declaration(m_source));
1826
m_lastDeclarations << decl;
1832
QList<DeclarationPointer> declarations = m_lastDeclarations;
1833
Instance oldInstance = m_lastInstance;
1835
QList<OverloadResolver::Parameter> oldParams = m_parameters;
1836
KDevVarLengthArray<AST*> oldParameterNodes = m_parameterNodes;
1838
//Backup the current use and invalidate it, we will update and create it after overload-resolution
1839
CurrentUse oldCurrentUse = m_currentUse;
1840
m_currentUse.isValid = false;
1844
bool fail = !buildParametersFromExpression(node->arguments);
1846
if( declarations.isEmpty() && !constructedType ) {
1848
if(MissingDeclarationType::Ptr missing = oldLastType.cast<Cpp::MissingDeclarationType>()) {
1849
missing->arguments = m_parameters;
1850
missing->isFunction = true;
1852
m_lastType = oldLastType;
1853
problem( node, "function-call: no matching declarations found" );
1859
if(declarations.isEmpty() && constructedType) {
1860
//Default-constructor is used
1861
m_lastType = AbstractType::Ptr(constructedType.unsafeData());
1862
DeclarationPointer decl(constructedType->declaration(topContext()));
1863
m_lastInstance = Instance(decl.data());
1864
m_lastDeclarations.clear();
1865
// m_lastDeclarations << decl;
1867
if(oldCurrentUse.isValid) {
1868
newUse( oldCurrentUse.node, oldCurrentUse.start_token, oldCurrentUse.end_token, decl );
1875
DeclarationPointer chosenFunction;
1876
KDevelop::DUContextPointer ptr(m_currentContext);
1877
OverloadResolver resolver( ptr, KDevelop::TopDUContextPointer(topContext()), oldInstance );
1880
chosenFunction = resolver.resolveList(m_parameters, convert(declarations));
1882
if( !chosenFunction && !m_strict ) {
1883
//Because we do not want to rely too much on our understanding of the code, we take the first function instead of totally failing.
1884
#ifdef DEBUG_FUNCTION_CALLS
1886
foreach(const OverloadResolver::Parameter& param, m_parameters)
1887
params += param.toString() + ", ";
1890
foreach(const DeclarationPointer &decl, declarations) {
1893
int defaultParamCount = 0;
1894
if( AbstractFunctionDeclaration* aDec = dynamic_cast<AbstractFunctionDeclaration*>(decl.data()) )
1895
defaultParamCount = aDec->defaultParameters().count();
1897
candidates += decl->toString() + QString(" default-params: %1").arg(defaultParamCount) + '\n';
1900
problem(node, QString("Could not find a function that matches the parameters. Using first candidate function. Parameters: %1 Candidates: %2").arg(params).arg(candidates));
1906
//Since not all parameters could be evaluated, Choose the first function
1907
chosenFunction = declarations.front();
1912
if( constructedType ) {
1913
//Constructor was called
1914
m_lastType = AbstractType::Ptr(constructedType.unsafeData());
1915
m_lastInstance = Instance(constructedType->declaration(topContext()));
1917
KDevelop::FunctionType::Ptr functionType = chosenFunction->abstractType().cast<KDevelop::FunctionType>();
1918
if( !chosenFunction || !functionType ) {
1919
problem( node, QString( "could not find a matching function for function-call" ) );
1921
m_lastType = functionType->returnType();
1922
m_lastInstance = Instance(chosenFunction);
1926
static IndexedString functionCallOperatorIdentifier("operator()");
1928
bool createUseOnParen = (bool)chosenFunction && (constructedType || chosenFunction->identifier().identifier() == functionCallOperatorIdentifier);
1929
//Re-create the use we have discarded earlier, this time with the correct overloaded function chosen.
1932
if(createUseOnParen) {
1933
if(oldCurrentUse.isValid)
1934
newUse( oldCurrentUse.node, oldCurrentUse.start_token, oldCurrentUse.end_token, oldCurrentUse.declaration );
1936
newUse( node , node->start_token, node->start_token+1, chosenFunction );
1937
}else if(oldCurrentUse.isValid) {
1938
newUse( oldCurrentUse.node, oldCurrentUse.start_token, oldCurrentUse.end_token, chosenFunction );
1941
m_parameterNodes = oldParameterNodes;
1942
m_parameters = oldParams;
1947
expressionType( node, m_lastType, m_lastInstance );
1950
void ExpressionVisitor::visitSignalSlotExpression(SignalSlotExpressionAST* node) {
1952
//So uses for the argument-types are built
1957
if(m_parameters.isEmpty())
1960
DUContext* container = 0;///@todo check whether signal/slot match, warn if not.
1962
StructureType::Ptr slotStructure = TypeUtils::targetType(TypeUtils::matchingClassPointer(qObjectPtrType(), TypeUtils::realType(m_parameters.back().type, m_topContext), m_topContext), m_topContext).cast<StructureType>();
1964
container = slotStructure->internalContext(m_topContext);
1967
Declaration* klass = Cpp::localClassFromCodeContext(m_currentContext);
1969
container = klass->internalContext();
1974
problem(node, QString("No signal/slot container"));
1979
problem(node, QString("Bad signal/slot"));
1984
SimpleCursor position = container->range().end;
1986
//This builds the uses
1987
NameASTVisitor nameV( m_session, this, container, topContext(), m_currentContext, position );
1988
nameV.run(node->name, true);
1993
CppEditorIntegrator editor(session());
1994
QByteArray tokenByteArray = editor.tokensToByteArray(node->name->id, node->name->end_token);
1997
if(node->name->end_token-1 >= node->name->id+2) {
1998
sig = QMetaObject::normalizedSignature( editor.tokensToByteArray(node->name->id+1, node->name->end_token) );
1999
sig = sig.mid(1, sig.length()-2);
2002
Identifier id(tokenFromIndex(node->name->id).symbol());
2005
foreach(Declaration* decl, container->findDeclarations(id, SimpleCursor::invalid(), m_topContext, (DUContext::SearchFlags)(DUContext::DontSearchInParent | DUContext::NoFiltering))) {
2006
QtFunctionDeclaration* qtFunction = dynamic_cast<QtFunctionDeclaration*>(decl);
2008
///Allow incomplete matching between the specified signature and the real signature, as Qt allows it.
2009
///@todo: For signals, we should only allow it when at least as many arguments are specified as in the slot declaration.
2010
///@todo: For slots, we should only allow it if the parameter has a default argument.
2011
uint functionSigLength = qtFunction->normalizedSignature().length();
2012
const char* functionSig = qtFunction->normalizedSignature().c_str();
2014
if(functionSigLength >= sig.length() &&
2015
strncmp(functionSig, sig.data(), sig.length()) == 0 &&
2016
(sig.isEmpty() || functionSigLength == sig.length() || functionSig[sig.length()] == ' ' || functionSig[sig.length()] == ','))
2020
newUse( node, node->name->id, node->name->id+1, DeclarationPointer(qtFunction) );
2028
void ExpressionVisitor::visitSubscriptExpression(SubscriptExpressionAST* node)
2031
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2033
Instance masterInstance = m_lastInstance;
2034
AbstractType::Ptr masterType = m_lastType;
2036
if( !masterType || !masterInstance ) {
2037
problem(node, "Tried subscript-expression on invalid object");
2044
//If the type the subscript-operator is applied on is a pointer, dereference it
2045
if( dereferenceLastPointer(node) ) {
2046
//Make visit the sub-expression, so uses are built
2049
masterInstance = m_lastInstance;
2050
masterType = m_lastType;
2052
visit(node->subscript); //Visit so uses are built
2055
m_lastType = masterType;
2056
m_lastInstance = masterInstance;
2063
visit(node->subscript);
2067
KDevelop::DUContextPointer ptr(m_currentContext);
2068
OverloadResolutionHelper helper( ptr, TopDUContextPointer(topContext()) );
2069
helper.setOperator( OverloadResolver::Parameter(masterType, isLValue( masterType, masterInstance ) ), "[]" );
2071
helper.setKnownParameters( OverloadResolver::Parameter( m_lastType, isLValue( m_lastType, m_lastInstance ) ) );
2072
QList<OverloadResolutionFunction> functions = helper.resolve(false);
2074
if( !functions.isEmpty() )
2076
KDevelop::FunctionType::Ptr function = functions.first().function.declaration()->type<KDevelop::FunctionType>();
2079
m_lastType = function->returnType();
2080
m_lastInstance = Instance(true);
2083
problem(node, QString("Found no subscript-function"));
2086
if( !functions.first().function.isViable() ) {
2087
problem(node, QString("Found no viable subscript-function, chosen function: %1").arg(functions.first().function.declaration() ? functions.first().function.declaration()->toString() : QString()));
2092
//Do not complain here, because we do not check for builtin operators
2093
//problem(node, "No fitting operator. found" );
2097
void ExpressionVisitor::visitSizeofExpression(SizeofExpressionAST* node) {
2098
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2099
visit(node->type_id);
2100
visit(node->expression);
2102
m_lastType = AbstractType::Ptr( new KDevelop::IntegralType(IntegralType::TypeInt) );
2103
m_lastInstance = Instance(true);
2106
void ExpressionVisitor::visitCondition(ConditionAST* node) {
2108
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2109
m_lastType = AbstractType::Ptr( new KDevelop::IntegralType(IntegralType::TypeBoolean) );
2110
m_lastInstance = Instance(true);
2113
void ExpressionVisitor::visitTypeId(TypeIdAST* type_id) {
2114
PushPositiveContext pushContext( m_currentContext, type_id->ducontext );
2115
visit(type_id->type_specifier);
2116
visit(type_id->declarator);
2119
AbstractType::Ptr ExpressionVisitor::qObjectPtrType() const {
2120
CppClassType::Ptr p(new CppClassType());
2121
p->setDeclarationId( DeclarationId(QualifiedIdentifier("QObject")) );
2122
PointerType::Ptr pointer(new PointerType);
2123
pointer->setBaseType(p.cast<AbstractType>());
2124
return pointer.cast<AbstractType>();
2127
void ExpressionVisitor::putStringType() {
2128
IntegralType::Ptr i(new KDevelop::IntegralType(IntegralType::TypeChar));
2129
i->setModifiers(AbstractType::ConstModifier);
2131
PointerType::Ptr p( new PointerType() );
2133
p->setBaseType( AbstractType::Ptr(i.unsafeData()) );
2135
m_lastType = p.cast<AbstractType>();
2136
m_lastInstance = Instance(true);
2140
void ExpressionVisitor::visitStringLiteral(StringLiteralAST* node) {
2142
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2147
void ExpressionVisitor::visitIncrDecrExpression(IncrDecrExpressionAST* node) {
2149
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2151
///post-fix increment/decrement like "i++" or "i--"
2152
///This does neither change the evaluated value, nor the type(except for overloaded operators)
2154
if( dynamic_cast<KDevelop::IntegralType*>(m_lastType.unsafeData()) ) {
2155
///Leave the type and its value alone
2157
///It is not an integral type, try finding an overloaded operator and use the return-value
2158
QString op = operatorNameFromTokenKind(tokenFromIndex(node->op).kind);
2162
KDevelop::DUContextPointer ptr(m_currentContext);
2163
OverloadResolutionHelper helper( ptr, TopDUContextPointer(topContext()) );
2164
helper.setOperator( OverloadResolver::Parameter(m_lastType, isLValue( m_lastType, m_lastInstance ) ), op );
2166
//Overloaded postfix operators have one additional int parameter
2167
static AbstractType::Ptr integer = AbstractType::Ptr(new ConstantIntegralType(IntegralType::TypeInt));
2168
helper.setKnownParameters( OverloadResolver::Parameter( integer, false ) );
2170
QList<OverloadResolutionFunction> functions = helper.resolve(false);
2172
if( !functions.isEmpty() )
2174
KDevelop::FunctionType::Ptr function = functions.first().function.declaration()->type<KDevelop::FunctionType>();
2175
if( functions.first().function.isViable() && function ) {
2176
m_lastType = function->returnType();
2177
m_lastInstance = Instance(true);
2179
problem(node, QString("Found no viable function"));
2183
newUse( node, node->op, node->op+1, functions.first().function.declaration() );
2185
//Do not complain here, because we do not check for builtin operators
2186
//problem(node, "No fitting operator. found" );
2192
expressionType( node, m_lastType, m_lastInstance );
2196
void ExpressionVisitor::visitNewTypeId(NewTypeIdAST* node) {
2197
//Return a pointer to the type
2202
void ExpressionVisitor::visitSimpleDeclaration(SimpleDeclarationAST* node) {
2203
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2204
///Simple type-specifiers like "int" are parsed as SimpleDeclarationAST, so treat them here.
2205
///Also we use this to parse constructor uses
2206
visit(node->type_specifier);
2207
QList< DeclarationPointer > oldLastDecls = m_lastDeclarations;
2208
AbstractType::Ptr oldLastType = m_lastType;
2209
Instance oldLastInstance = m_lastInstance;
2211
if(node->init_declarators)
2213
const ListNode<InitDeclaratorAST*>
2214
*it = node->init_declarators->toFront(),
2219
//Make sure each init-declarator gets the same type assigned
2220
m_lastDeclarations = oldLastDecls;
2221
m_lastType = oldLastType;
2222
m_lastInstance = oldLastInstance;
2230
visit(node->win_decl_specifiers);
2233
void ExpressionVisitor::visitDeclarationStatement(DeclarationStatementAST* node) {
2234
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2235
///Simple type-specifiers like "int" are parsed as SimpleDeclarationAST, so treat them here.
2236
visit( node->declaration );
2238
void ExpressionVisitor::visitThrowExpression(ThrowExpressionAST* node) {
2239
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2240
visit( node->expression );
2242
void ExpressionVisitor::visitDeleteExpression(DeleteExpressionAST* node) {
2243
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2244
visit( node->expression );
2247
void ExpressionVisitor::visitNewInitializer(NewInitializerAST* node) {
2248
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2249
visit(node->expression);
2252
void ExpressionVisitor::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST* node) {
2253
//Happens as template-parameter
2254
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2256
///@todo respect const etc.
2259
void ExpressionVisitor::visitMemInitializer(MemInitializerAST* node) {
2261
PushPositiveContext pushContext( m_currentContext, node->ducontext );
2264
Declaration* klass = localClassFromCodeContext(m_currentContext);
2266
m_lastType = klass->abstractType();
2269
m_memberAccess = true;
2270
visit(node->initializer_id);
2271
m_memberAccess = false;
2273
AbstractType::Ptr itemType = m_lastType;
2274
Instance oldLastInstance = m_lastInstance;
2275
QList< DeclarationPointer > declarations = m_lastDeclarations;
2276
if (buildParametersFromExpression(node->expression)) {
2277
// build use for the ctor of the base class, see also visitInitDeclarator
2278
DeclarationPointer chosenFunction;
2282
KDevelop::DUContextPointer ptr(m_currentContext);
2283
OverloadResolver resolver( ptr, KDevelop::TopDUContextPointer(topContext()), oldLastInstance );
2285
chosenFunction = resolver.resolveList(m_parameters, convert(declarations));
2288
if (chosenFunction) {
2289
uint token = node->initializer_id->end_token;
2290
newUse( node , token, token+1, chosenFunction );
2294
visit(node->expression);
2295
TypePtr< MissingDeclarationType > missingDeclType = itemType.cast<MissingDeclarationType>();
2297
if(m_lastType && missingDeclType) {
2298
Cpp::ExpressionEvaluationResult res;
2299
res.type = m_lastType->indexed();
2300
res.isInstance = m_lastInstance;
2301
missingDeclType->assigned = res;
2305
///Nodes that are invalid inside an expression:
2306
void ExpressionVisitor::visitPtrToMember(PtrToMemberAST* node) { DefaultVisitor::visitPtrToMember(node); }
2307
void ExpressionVisitor::visitOperatorFunctionId(OperatorFunctionIdAST* node) { DefaultVisitor::visitOperatorFunctionId(node); }
2308
void ExpressionVisitor::visitTypeIdentification(TypeIdentificationAST* node) { DefaultVisitor::visitTypeIdentification(node); }
2309
void ExpressionVisitor::visitUnqualifiedName(UnqualifiedNameAST* node) { DefaultVisitor::visitUnqualifiedName(node); }
2310
void ExpressionVisitor::visitOperator(OperatorAST* node) { DefaultVisitor::visitOperator(node); }
2311
void ExpressionVisitor::visitAccessSpecifier(AccessSpecifierAST* node) { DefaultVisitor::visitAccessSpecifier(node); }
2312
void ExpressionVisitor::visitAsmDefinition(AsmDefinitionAST* node) { DefaultVisitor::visitAsmDefinition(node); }
2313
void ExpressionVisitor::visitBaseClause(BaseClauseAST* node) { DefaultVisitor::visitBaseClause(node); }
2314
void ExpressionVisitor::visitBaseSpecifier(BaseSpecifierAST* node) { DefaultVisitor::visitBaseSpecifier(node); }
2315
void ExpressionVisitor::visitClassSpecifier(ClassSpecifierAST* node) { DefaultVisitor::visitClassSpecifier(node); }
2317
void ExpressionVisitor::visitCtorInitializer(CtorInitializerAST* node) { DefaultVisitor::visitCtorInitializer(node); }
2318
void ExpressionVisitor::visitDoStatement(DoStatementAST* node) { DefaultVisitor::visitDoStatement(node); }
2319
void ExpressionVisitor::visitEnumSpecifier(EnumSpecifierAST* node) { DefaultVisitor::visitEnumSpecifier(node); }
2320
void ExpressionVisitor::visitEnumerator(EnumeratorAST* node) { DefaultVisitor::visitEnumerator(node); }
2321
void ExpressionVisitor::visitExceptionSpecification(ExceptionSpecificationAST* node) { DefaultVisitor::visitExceptionSpecification(node); }
2322
void ExpressionVisitor::visitForStatement(ForStatementAST* node) { DefaultVisitor::visitForStatement(node); }
2323
void ExpressionVisitor::visitFunctionDefinition(FunctionDefinitionAST* node) { DefaultVisitor::visitFunctionDefinition(node); }
2324
void ExpressionVisitor::visitIfStatement(IfStatementAST* node) { DefaultVisitor::visitIfStatement(node); }
2325
void ExpressionVisitor::visitLabeledStatement(LabeledStatementAST* node) { DefaultVisitor::visitLabeledStatement(node); }
2326
void ExpressionVisitor::visitLinkageBody(LinkageBodyAST* node) { DefaultVisitor::visitLinkageBody(node); }
2327
void ExpressionVisitor::visitLinkageSpecification(LinkageSpecificationAST* node) { DefaultVisitor::visitLinkageSpecification(node); }
2328
void ExpressionVisitor::visitNamespace(NamespaceAST* node) { DefaultVisitor::visitNamespace(node); }
2329
void ExpressionVisitor::visitNamespaceAliasDefinition(NamespaceAliasDefinitionAST* node) { DefaultVisitor::visitNamespaceAliasDefinition(node); }
2330
void ExpressionVisitor::visitParameterDeclaration(ParameterDeclarationAST* node) { DefaultVisitor::visitParameterDeclaration(node); }
2331
void ExpressionVisitor::visitParameterDeclarationClause(ParameterDeclarationClauseAST* node) { DefaultVisitor::visitParameterDeclarationClause(node); }
2332
void ExpressionVisitor::visitReturnStatement(ReturnStatementAST* node) { DefaultVisitor::visitReturnStatement(node); }
2333
void ExpressionVisitor::visitSwitchStatement(SwitchStatementAST* node) { DefaultVisitor::visitSwitchStatement(node); }
2334
void ExpressionVisitor::visitTemplateArgument(TemplateArgumentAST* node) { DefaultVisitor::visitTemplateArgument(node); }
2335
void ExpressionVisitor::visitTemplateDeclaration(TemplateDeclarationAST* node) { DefaultVisitor::visitTemplateDeclaration(node); }
2336
void ExpressionVisitor::visitTemplateParameter(TemplateParameterAST* node) { DefaultVisitor::visitTemplateParameter(node); }
2337
void ExpressionVisitor::visitTryBlockStatement(TryBlockStatementAST* node) { DefaultVisitor::visitTryBlockStatement(node); }
2338
void ExpressionVisitor::visitTypeParameter(TypeParameterAST* node) { DefaultVisitor::visitTypeParameter(node); }
2339
void ExpressionVisitor::visitTypedef(TypedefAST* node) { DefaultVisitor::visitTypedef(node); }
2340
void ExpressionVisitor::visitUsing(UsingAST* node) { DefaultVisitor::visitUsing(node); }
2341
void ExpressionVisitor::visitUsingDirective(UsingDirectiveAST* node) { DefaultVisitor::visitUsingDirective(node); }
2342
void ExpressionVisitor::visitWhileStatement(WhileStatementAST* node) { DefaultVisitor::visitWhileStatement(node); }
2343
void ExpressionVisitor::visitWinDeclSpec(WinDeclSpecAST* node) { DefaultVisitor::visitWinDeclSpec(node); }