Ticket #34545: declarationbuilder.cpp

File declarationbuilder.cpp, 64.6 KB (added by dragan.glumac@…, 12 years ago)
Line 
1/* This file is part of KDevelop
2    Copyright 2006-2007 Hamish Rodda <rodda@kde.org>
3    Copyright 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
4
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Library General Public
7   License version 2 as published by the Free Software Foundation.
8
9   This library is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   Library General Public License for more details.
13
14   You should have received a copy of the GNU Library General Public License
15   along with this library; see the file COPYING.LIB.  If not, write to
16   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17   Boston, MA 02110-1301, USA.
18*/
19
20#include "declarationbuilder.h"
21
22#include "debugbuilders.h"
23
24#include <QByteArray>
25#include <typeinfo>
26#include <iterator>
27
28#include "templatedeclaration.h"
29
30#include "parser/type_compiler.h"
31#include "parser/commentformatter.h"
32
33#include <language/duchain/forwarddeclaration.h>
34#include <language/duchain/duchain.h>
35#include <language/duchain/duchainlock.h>
36#include <language/duchain/repositories/itemrepository.h>
37#include <language/duchain/types/identifiedtype.h>
38#include <language/duchain/namespacealiasdeclaration.h>
39#include <language/duchain/aliasdeclaration.h>
40#include <util/pushvalue.h>
41
42#include "qtfunctiondeclaration.h"
43#include "qpropertydeclaration.h"
44#include "cppeditorintegrator.h"
45#include "name_compiler.h"
46#include <language/duchain/classfunctiondeclaration.h>
47#include <language/duchain/functiondeclaration.h>
48#include <language/duchain/functiondefinition.h>
49#include "templateparameterdeclaration.h"
50#include "type_compiler.h"
51#include "tokens.h"
52#include "parsesession.h"
53#include "cpptypes.h"
54#include "cppduchain.h"
55#include "cpptypes.h"
56#include <language/duchain/classdeclaration.h>
57
58#include "cppdebughelper.h"
59#include "name_visitor.h"
60#include "usebuilder.h"
61
62#include "overloadresolutionhelper.h"
63
64using namespace KTextEditor;
65using namespace KDevelop;
66using namespace Cpp;
67
68ClassDeclarationData::ClassType classTypeFromTokenKind(int kind)
69{
70  switch(kind)
71  {
72  case Token_struct:
73    return ClassDeclarationData::Struct;
74  case Token_union:
75    return ClassDeclarationData::Union;
76  default:
77    return ClassDeclarationData::Class;
78  }
79}
80
81bool DeclarationBuilder::changeWasSignificant() const
82{
83  ///@todo Also set m_changeWasSignificant if publically visible declarations were removed(needs interaction with abstractcontextbuilder)
84  return m_changeWasSignificant;
85}
86
87DeclarationBuilder::DeclarationBuilder (ParseSession* session)
88  : DeclarationBuilderBase(session), m_changeWasSignificant(false), m_ignoreDeclarators(false), m_functionFlag(NoFunctionFlag), m_collectQtFunctionSignature(false), m_lastDeclaration(0)
89{
90}
91
92ReferencedTopDUContext DeclarationBuilder::buildDeclarations(Cpp::EnvironmentFilePointer file, AST *node, IncludeFileList* includes, const ReferencedTopDUContext& updateContext, bool removeOldImports)
93{
94  ReferencedTopDUContext top = buildContexts(file, node, includes, updateContext, removeOldImports);
95
96  Q_ASSERT(m_accessPolicyStack.isEmpty());
97  Q_ASSERT(m_functionDefinedStack.isEmpty());
98
99  return top;
100}
101
102void DeclarationBuilder::visitTemplateParameter(TemplateParameterAST * ast) {
103 
104  //Backup and zero the parameter declaration, because we will handle it here directly, and don't want a normal one to be created
105 
106  m_ignoreDeclarators = true;
107  DeclarationBuilderBase::visitTemplateParameter(ast);
108  m_ignoreDeclarators = false;
109 
110  if( ast->type_parameter || ast->parameter_declaration ) {
111    ///@todo deal with all the other stuff the AST may contain
112    TemplateParameterDeclaration* decl;
113    if(ast->type_parameter)
114      decl = openDeclaration<TemplateParameterDeclaration>(ast->type_parameter->name, ast, Identifier(), false, !ast->type_parameter->name);
115    else
116      decl = openDeclaration<TemplateParameterDeclaration>(ast->parameter_declaration->declarator ? ast->parameter_declaration->declarator->id : 0, ast, Identifier(), false, !ast->parameter_declaration->declarator);
117
118    DUChainWriteLocker lock(DUChain::lock());
119    AbstractType::Ptr type = lastType();
120    if( type.cast<CppTemplateParameterType>() ) {
121      type.cast<CppTemplateParameterType>()->setDeclaration(decl);
122    } else {
123      kDebug(9007) << "bad last type";
124    }
125    decl->setAbstractType(type);
126
127    if( ast->type_parameter && ast->type_parameter->type_id ) {
128      //Extract default type-parameter
129      QualifiedIdentifier defaultParam;
130
131      QString str;
132      ///Only record the strings, because these expressions may depend on template-parameters and thus must be evaluated later
133      str += stringFromSessionTokens( editor()->parseSession(), ast->type_parameter->type_id->start_token, ast->type_parameter->type_id->end_token );
134
135      defaultParam = QualifiedIdentifier(str);
136
137      decl->setDefaultParameter(defaultParam);
138    }
139
140    if( ast->parameter_declaration ) {
141      if( ast->parameter_declaration->expression )
142        decl->setDefaultParameter( QualifiedIdentifier( stringFromSessionTokens( editor()->parseSession(), ast->parameter_declaration->expression->start_token, ast->parameter_declaration->expression->end_token ) ) );
143    }
144    closeDeclaration(ast->parameter_declaration);
145  }
146}
147
148void DeclarationBuilder::parseComments(const ListNode<uint> *comments)
149{
150  setComment(editor()->parseSession()->m_commentFormatter.formatComment(comments, editor()->parseSession()));
151}
152
153void DeclarationBuilder::visitFunctionDeclaration(FunctionDefinitionAST* node)
154{
155  FunctionFlag flag = NoFunctionFlag;
156  switch(node->defaultDeleted) {
157    case FunctionDefinitionAST::NotDefaultOrDeleted:
158      flag = NoFunctionFlag;
159      break;
160    case FunctionDefinitionAST::Default:
161      flag = DefaultFunction;
162      break;
163    case FunctionDefinitionAST::Deleted:
164      flag = DeleteFunction;
165      break;
166  }
167  PushValue<FunctionFlag> setDefaultDeleted(m_functionFlag, flag);
168
169  parseComments(node->comments);
170  parseStorageSpecifiers(node->storage_specifiers);
171  parseFunctionSpecifiers(node->function_specifiers);
172 
173  //Used to map to the top level function node once the Declaration is built
174  if(m_mapAst)
175    m_mappedNodes.push(node);
176 
177  m_functionDefinedStack.push(node->start_token);
178
179  DeclarationBuilderBase::visitFunctionDeclaration(node);
180
181  m_functionDefinedStack.pop();
182 
183  if(m_mapAst)
184    m_mappedNodes.pop();
185
186  popSpecifiers();
187}
188
189//Visitor that clears the ducontext from all AST nodes
190struct ClearDUContextVisitor : public DefaultVisitor {
191
192  virtual void visit(AST* node) {
193    if(node)
194      node->ducontext = 0;
195    DefaultVisitor::visit(node);
196  }
197};
198
199void DeclarationBuilder::visitInitDeclarator(InitDeclaratorAST *node)
200{
201  ///FIXME: properly add support for member-declaration/member-declarator
202  PushValue<FunctionFlag> setHasInitialize(m_functionFlag,
203    (node->initializer && node->initializer->initializer_clause && node->initializer->initializer_clause->expression)
204      ? AbstractFunction : NoFunctionFlag);
205
206  if(currentContext()->type() == DUContext::Other) {
207    //Cannot declare a a function within a code-context
208    node->declarator->parameter_is_initializer = true;
209  }else if(!m_inFunctionDefinition && node->declarator && node->declarator->parameter_declaration_clause && node->declarator->id) {
210    //Decide whether the parameter-declaration clause is valid
211    DUChainWriteLocker lock(DUChain::lock());
212    CursorInRevision pos = editor()->findPosition(node->start_token, CppEditorIntegrator::FrontEdge);
213   
214    QualifiedIdentifier id;
215    identifierForNode(node->declarator->id, id);   
216    DUContext* previous = currentContext();
217
218    DUContext* previousLast = lastContext();
219    QVector<KDevelop::DUContext::Import> importedParentContexts = m_importedParentContexts;
220   
221    openPrefixContext(node, id, pos); //We create a temporary prefix-context to search from within the right scope
222   
223    DUContext* tempContext = currentContext();
224    if (currentContext()->type() != DUContext::Class)
225      node->declarator->parameter_is_initializer = !checkParameterDeclarationClause(node->declarator->parameter_declaration_clause);
226    closePrefixContext(id);
227   
228   
229   
230    if(tempContext != previous) {
231     
232      //We remove all of its traces from the AST using ClearDUContextVisitor.
233      ClearDUContextVisitor clear;
234      clear.visit(node);
235
236      ///@todo We don't delete the tempContext, as that may cause crashes. Problem: This leaves garbage in the duchain
237      ///@todo Solve the redundancy issue once and for all, properly, using a SimpleDeclarationOrFunctionDeclarationAST or similar.
238     
239      //Since we don't delete the temporary context, at least collapse its range.
240      tempContext->setRange(RangeInRevision(tempContext->range().start, tempContext->range().end));
241     
242      setLastContext(previousLast);
243      m_importedParentContexts = importedParentContexts;
244    }
245    Q_ASSERT(currentContext() == previous);
246  }
247 
248  DeclarationBuilderBase::visitInitDeclarator(node);
249}
250
251void DeclarationBuilder::visitQPropertyDeclaration(QPropertyDeclarationAST* node)
252{
253  QPropertyDeclaration *decl = openDeclaration<QPropertyDeclaration>(node->name, node->name);
254  decl->setIsStored(node->stored);
255  decl->setIsUser(node->user);
256  decl->setIsConstant(node->constant);
257  decl->setIsFinal(node->final);
258
259  DeclarationBuilderBase::visitQPropertyDeclaration(node);
260  AbstractType::Ptr type = lastType();
261  closeDeclaration(true);
262
263  if(type) {
264    DUChainWriteLocker lock(DUChain::lock());
265    decl->setAbstractType(type);
266    decl->setAccessPolicy(KDevelop::Declaration::Public);
267  }
268
269  m_pendingPropertyDeclarations.insert(currentContext(), qMakePair(decl, node));
270}
271
272void DeclarationBuilder::visitForRangeDeclaration(ForRangeDeclarationAst* node)
273{
274  AbstractType::Ptr listType = lastType();
275
276  DefaultVisitor::visitForRangeDeclaration(node);
277
278  if (lastTypeWasAuto() && listType && m_lastDeclaration) {
279    // auto support for range-based for
280    AbstractType::Ptr realListType = TypeUtils::realType(listType);
281    // step 1: find type of elements in list
282    AbstractType::Ptr elementType;
283    if (ArrayType::Ptr array = realListType.cast<ArrayType>()) {
284      // case a: c-array, i.e. foo bar[5]; -> type is foo
285      elementType = array->elementType();
286    } else {
287      // case b: look for begin(listType) function using ADL
288      DUChainReadLocker lock;
289      OverloadResolutionHelper helper = OverloadResolutionHelper( DUContextPointer(currentContext()), TopDUContextPointer(topContext()) );
290      static const QualifiedIdentifier begin("begin");
291      helper.setFunctionNameForADL(begin);
292      helper.setKnownParameters(OverloadResolver::ParameterList(listType, false));
293      helper.setFunctions( currentContext()->findDeclarations(begin, CursorInRevision::invalid(), AbstractType::Ptr(), 0, DUContext::OnlyFunctions) );
294      ViableFunction func = helper.resolve();
295      if (func.isValid()) {
296        AbstractType::Ptr type = func.declaration()->type<FunctionType>()->returnType();
297        // see spec: for-range-declaration = *__begin;
298        elementType = TypeUtils::decreasePointerDepth(type, topContext(), true);
299      }
300    }
301
302    // step 2: set last type, but keep const&
303    if (elementType) {
304      DUChainWriteLocker lock;
305      AbstractType::Ptr type = m_lastDeclaration->abstractType();
306      elementType->setModifiers(type->modifiers());
307      if (ReferenceType::Ptr ref = type.cast<ReferenceType>()) {
308        ref->setBaseType(elementType);
309      } else {
310        type = elementType;
311      }
312      m_lastDeclaration->setAbstractType(type);
313    }
314  }
315}
316
317KDevelop::IndexedDeclaration DeclarationBuilder::resolveMethodName(NameAST *node)
318{
319  QualifiedIdentifier id;
320  identifierForNode(node, id);
321
322  DUChainReadLocker lock(DUChain::lock());
323  if(currentDeclaration() && currentDeclaration()->internalContext()) {
324    const QList<Declaration*> declarations = currentDeclaration()->internalContext()->findDeclarations(id, CursorInRevision::invalid(), AbstractType::Ptr(), 0, DUContext::OnlyFunctions);
325    if(!declarations.isEmpty())
326      return KDevelop::IndexedDeclaration(declarations.first());
327  }
328
329  return KDevelop::IndexedDeclaration();
330}
331
332void DeclarationBuilder::resolvePendingPropertyDeclarations(const QList<PropertyResolvePair> &pairs)
333{
334  foreach(const PropertyResolvePair &pair, pairs) {
335    if(pair.second->getter){
336      const KDevelop::IndexedDeclaration declaration = resolveMethodName(pair.second->getter);
337      if(declaration.isValid())
338        pair.first->setReadMethod(declaration);
339    }
340    if(pair.second->setter){
341      const KDevelop::IndexedDeclaration declaration = resolveMethodName(pair.second->setter);
342      if(declaration.isValid())
343        pair.first->setWriteMethod(declaration);
344    }
345    if(pair.second->resetter){
346      const KDevelop::IndexedDeclaration declaration = resolveMethodName(pair.second->resetter);
347      if(declaration.isValid())
348        pair.first->setResetMethod(declaration);
349    }
350    if(pair.second->notifier){
351      const KDevelop::IndexedDeclaration declaration = resolveMethodName(pair.second->notifier);
352      if(declaration.isValid())
353        pair.first->setNotifyMethod(declaration);
354    }
355    if(pair.second->designableMethod){
356      const KDevelop::IndexedDeclaration declaration = resolveMethodName(pair.second->designableMethod);
357      if(declaration.isValid())
358        pair.first->setDesignableMethod(declaration);
359    }
360    if(pair.second->scriptableMethod){
361      const KDevelop::IndexedDeclaration declaration = resolveMethodName(pair.second->scriptableMethod);
362      if(declaration.isValid())
363        pair.first->setScriptableMethod(declaration);
364    }
365  }
366}
367
368void DeclarationBuilder::visitSimpleDeclaration(SimpleDeclarationAST* node)
369{
370  parseComments(node->comments);
371  parseStorageSpecifiers(node->storage_specifiers);
372  parseFunctionSpecifiers(node->function_specifiers);
373
374  if(m_mapAst)
375    m_mappedNodes.push(node);
376 
377  m_functionDefinedStack.push(0);
378
379  DeclarationBuilderBase::visitSimpleDeclaration(node);
380
381  m_functionDefinedStack.pop();
382 
383  if(m_mapAst)
384    m_mappedNodes.pop();
385
386  popSpecifiers();
387}
388
389void DeclarationBuilder::visitDeclarator (DeclaratorAST* node)
390{
391  if(m_ignoreDeclarators) {
392    DeclarationBuilderBase::visitDeclarator(node);
393    return;
394  }
395  //need to make backup because we may temporarily change it
396  ParameterDeclarationClauseAST* parameter_declaration_clause_backup = node->parameter_declaration_clause;
397
398  m_collectQtFunctionSignature = !m_accessPolicyStack.isEmpty() && ((m_accessPolicyStack.top() & FunctionIsSlot) || (m_accessPolicyStack.top() & FunctionIsSignal));
399  m_qtFunctionSignature = QByteArray();
400 
401  if (node->parameter_declaration_clause && !node->parameter_is_initializer) {
402
403    if(m_collectQtFunctionSignature) //We need to do this just to collect the signature
404      checkParameterDeclarationClause(node->parameter_declaration_clause);
405   
406    Declaration* decl = openFunctionDeclaration(node->id, node);
407   
408    ///Create mappings iff the AST feature is specified
409    if(m_mapAst && !m_mappedNodes.empty())
410      editor()->parseSession()->mapAstDuChain(m_mappedNodes.top(), KDevelop::DeclarationPointer(decl));
411
412    if (m_functionFlag == DeleteFunction) {
413      DUChainWriteLocker lock(DUChain::lock());
414      decl->setExplicitlyDeleted(true);
415    }
416
417    if( !m_functionDefinedStack.isEmpty() ) {
418        DUChainWriteLocker lock(DUChain::lock());
419        // don't overwrite isDefinition if that was already set (see openFunctionDeclaration)
420        decl->setDeclarationIsDefinition( (bool)m_functionDefinedStack.top() );
421    }
422
423    applyFunctionSpecifiers();
424  } else {
425    openDefinition(node->id, node, node->id == 0);
426    node->parameter_declaration_clause = 0;
427  }
428
429  m_collectQtFunctionSignature = false;
430
431  applyStorageSpecifiers();
432
433  DeclarationBuilderBase::visitDeclarator(node);
434
435  if (node->parameter_declaration_clause) {
436    if (!m_functionDefinedStack.isEmpty() && m_functionDefinedStack.top() && node->id) {
437
438      DUChainWriteLocker lock(DUChain::lock());
439      //We have to search for the fully qualified identifier, so we always get the correct class
440      QualifiedIdentifier id = currentContext()->scopeIdentifier(false);
441      QualifiedIdentifier id2;
442      identifierForNode(node->id, id2);
443      id += id2;
444     
445      id.setExplicitlyGlobal(true);
446
447      if (id.count() > 1 ||
448           (m_inFunctionDefinition && (currentContext()->type() == DUContext::Namespace || currentContext()->type() == DUContext::Global))) {
449        CursorInRevision pos = currentDeclaration()->range().start;//editor()->findPosition(m_functionDefinedStack.top(), CppEditorIntegrator::FrontEdge);
450        // TODO: potentially excessive locking
451
452        QList<Declaration*> declarations = currentContext()->findDeclarations(id, pos, AbstractType::Ptr(), 0, DUContext::OnlyFunctions);
453
454        FunctionType::Ptr currentFunction = lastType().cast<FunctionType>();
455        int functionArgumentCount = 0;
456        if(currentFunction)
457          functionArgumentCount = currentFunction->arguments().count();
458
459        for( int cycle = 0; cycle < 3; cycle++ ) {
460          bool found = false;
461          ///We do 2 cycles: In the first cycle, we want an exact match. In the second, we accept approximate matches.
462          foreach (Declaration* dec, declarations) {
463            if (dec->isForwardDeclaration())
464              continue;
465            if(dec == currentDeclaration() || dec->isDefinition())
466              continue;
467            //Compare signatures of function-declarations:
468            if(dec->abstractType()->indexed() == lastType()->indexed())
469            {
470              //The declaration-type matches this definition, good.
471            }else{
472              if(cycle == 0) {
473                //First cycle, only accept exact matches
474                continue;
475              }else if(cycle == 1){
476                //Second cycle, match by argument-count
477                FunctionType::Ptr matchFunction = dec->type<FunctionType>();
478                if(currentFunction && matchFunction && currentFunction->arguments().count() == functionArgumentCount ) {
479                  //We have a match
480                }else{
481                  continue;
482                }
483              }else if(cycle == 2){
484                //Accept any match, so just continue
485              }
486              if(FunctionDefinition::definition(dec) && wasEncountered(FunctionDefinition::definition(dec)))
487                continue; //Do not steal declarations
488            }
489
490            if(FunctionDefinition* funDef = dynamic_cast<FunctionDefinition*>(currentDeclaration())) {
491              funDef->setDeclaration(dec);
492            }
493
494            found = true;
495            break;
496          }
497          if(found)
498            break;
499        }
500      }
501    }
502  }
503
504  closeDeclaration();
505
506  node->parameter_declaration_clause = parameter_declaration_clause_backup;
507}
508
509ForwardDeclaration * DeclarationBuilder::openForwardDeclaration(NameAST * name, AST * range)
510{
511  return openDeclaration<ForwardDeclaration>(name, range);
512}
513
514template<class Type>
515Type hasTemplateContext( const QList<Type>& contexts ) {
516  foreach( const Type& context, contexts )
517    if( context && context->type() == KDevelop::DUContext::Template )
518      return context;
519  return Type(0);
520}
521
522DUContext::Import hasTemplateContext( const QVector<DUContext::Import>& contexts, TopDUContext* top ) {
523  foreach( const DUContext::Import& context, contexts )
524    if( context.context(top) && context.context(top)->type() == KDevelop::DUContext::Template )
525      return context;
526
527  return DUContext::Import();
528}
529
530//Check whether the given context is a template-context by checking whether it imports a template-parameter context
531KDevelop::DUContext* isTemplateContext( KDevelop::DUContext* context ) {
532  return hasTemplateContext( context->importedParentContexts(), context->topContext() ).context(context->topContext());
533}
534
535template<class T>
536T* DeclarationBuilder::openDeclaration(NameAST* name, AST* rangeNode, const Identifier& customName, bool collapseRangeAtStart, bool collapseRangeAtEnd)
537{
538  DUChainWriteLocker lock(DUChain::lock());
539
540  KDevelop::DUContext* templateCtx = hasTemplateContext(m_importedParentContexts, topContext()).context(topContext());
541
542  ///We always need to create a template declaration when we're within a template, so the declaration can be accessed
543  ///by specialize(..) and its indirect DeclarationId
544  if( templateCtx || m_templateDeclarationDepth ) {
545    Cpp::SpecialTemplateDeclaration<T>* ret = openDeclarationReal<Cpp::SpecialTemplateDeclaration<T> >( name, rangeNode, customName, collapseRangeAtStart, collapseRangeAtEnd );
546    ret->setTemplateParameterContext(templateCtx);
547    return ret;
548  } else{
549    return openDeclarationReal<T>( name, rangeNode, customName, collapseRangeAtStart, collapseRangeAtEnd );
550  }
551}
552
553template<class T>
554T* DeclarationBuilder::openDeclarationReal(NameAST* name, AST* rangeNode, const Identifier& customName, bool collapseRangeAtStart, bool collapseRangeAtEnd, const RangeInRevision* customRange)
555{
556  RangeInRevision newRange;
557  if(name) {
558    uint start = name->unqualified_name->start_token;
559    uint end = name->unqualified_name->end_token;
560
561    //We must exclude the tilde. Else we may get totally messed up ranges when the name of a destructor is renamed in a macro
562    if(name->unqualified_name->tilde)
563      start = name->unqualified_name->tilde+1;
564
565    newRange = editor()->findRange(start, end);
566  }else if(rangeNode) {
567    newRange = editor()->findRange(rangeNode);
568  }else if(customRange) {
569    newRange = *customRange;
570  }
571
572  if(collapseRangeAtStart)
573    newRange.end = newRange.start;
574  else if(collapseRangeAtEnd)
575    newRange.start = newRange.end;
576
577  Identifier localId = customName;
578
579  if (name) {
580    //If this is an operator thing, build the type first. Since it's part of the name, the type-builder doesn't catch it normally
581    if(name->unqualified_name && name->unqualified_name->operator_id)
582      visit(name->unqualified_name->operator_id);
583   
584    QualifiedIdentifier id;
585    identifierForNode(name, id);
586
587    if(localId.isEmpty())
588      localId = id.last();
589  }
590
591  T* declaration = 0;
592
593  if (recompiling()) {
594    // Seek a matching declaration
595
596    ///@todo maybe order the declarations within ducontext and change here back to walking the indices, because that's easier to debug and faster
597    QList<Declaration*> decls = currentContext()->findLocalDeclarations(localId, CursorInRevision::invalid(), 0, AbstractType::Ptr(), DUContext::NoFiltering);
598    foreach( Declaration* dec, decls ) {
599
600      if( wasEncountered(dec) )
601        continue;
602
603      if (dec->range() == newRange &&
604          (localId == dec->identifier() || (localId.isUnique() && dec->identifier().isUnique())) &&
605          typeid(T) == typeid(*dec)
606         )
607      {
608        // Match
609        TemplateDeclaration* templateDecl = dynamic_cast<TemplateDeclaration*>(dec);
610        if(templateDecl)
611          templateDecl->deleteAllInstantiations(); //Delete all instantiations so we have a fresh start
612       
613        declaration = dynamic_cast<T*>(dec);
614        break;
615      }
616    }
617
618    if(!declaration) {
619      ///Second run of the above, this time ignoring the ranges.
620      foreach( Declaration* dec, decls ) {
621        if( wasEncountered(dec) )
622          continue;
623       
624        if ((localId == dec->identifier() || (localId.isUnique() && dec->identifier().isUnique())) &&
625            typeid(*dec) == typeid(T)
626          )
627        {
628          // Match
629          declaration = dynamic_cast<T*>(dec);
630          declaration->setRange(newRange);
631          break;
632        }
633      }
634    }
635  }
636#ifdef DEBUG_UPDATE_MATCHING
637  if(declaration)
638    kDebug() << "found match for" << localId.toString();
639  else
640    kDebug() << "nothing found for" << localId.toString();
641#endif
642
643  if (!declaration) {
644    if(currentContext()->inSymbolTable())
645      m_changeWasSignificant = true; //We are adding a declaration that comes into the symbol table, so mark the change significant
646
647    declaration = new T(newRange, currentContext());
648    declaration->setIdentifier(localId);
649  }
650
651  //Clear some settings
652  AbstractFunctionDeclaration* funDecl = dynamic_cast<AbstractFunctionDeclaration*>(declaration);
653  if(funDecl)
654    funDecl->clearDefaultParameters();
655
656  declaration->setDeclarationIsDefinition(false); //May be set later
657
658  declaration->setIsTypeAlias(m_inTypedef);
659
660  if( localId.templateIdentifiersCount() ) {
661    TemplateDeclaration* templateDecl = dynamic_cast<TemplateDeclaration*>(declaration);
662    if( declaration && templateDecl ) {
663      ///This is a template-specialization. Find the class it is specialized from.
664      localId.clearTemplateIdentifiers();
665
666      ///@todo Make sure the searched class is in the same namespace
667      QList<Declaration*> decls = currentContext()->findDeclarations(QualifiedIdentifier(localId), editor()->findPosition(name->start_token, CppEditorIntegrator::FrontEdge) );
668
669      if( !decls.isEmpty() )
670      {
671        foreach( Declaration* decl, decls )
672          if( TemplateDeclaration* baseTemplateDecl = dynamic_cast<TemplateDeclaration*>(decl) ) {
673            templateDecl->setSpecializedFrom(baseTemplateDecl);
674            break;
675          }
676
677        if( !templateDecl->specializedFrom().isValid() )
678          kDebug(9007) << "Could not find valid specialization-base" << localId.toString() << "for" << declaration->toString();
679      }
680    } else {
681      kDebug(9007) << "Specialization of non-template class" << declaration->toString();
682    }
683
684  }
685
686  declaration->setComment(comment());
687  clearComment();
688
689  setEncountered(declaration);
690
691  m_declarationStack.push(declaration);
692
693  return declaration;
694}
695
696ClassDeclaration* DeclarationBuilder::openClassDefinition(NameAST* name, AST* range, bool collapseRange, ClassDeclarationData::ClassType classType) {
697  Identifier id;
698
699  if(!name) {
700    //Unnamed class/struct, use a unique id
701    static QAtomicInt& uniqueClassNumber( KDevelop::globalItemRepositoryRegistry().getCustomCounter("Unnamed Class Ids", 1) );
702    id = Identifier::unique( uniqueClassNumber.fetchAndAddRelaxed(1) );
703  }
704
705  ClassDeclaration* ret = openDeclaration<ClassDeclaration>(name, range, id, collapseRange);
706  DUChainWriteLocker lock(DUChain::lock());
707  ret->setDeclarationIsDefinition(true);
708  ret->clearBaseClasses();
709 
710  if(m_accessPolicyStack.isEmpty())
711    ret->setAccessPolicy(KDevelop::Declaration::Public);
712  else
713    ret->setAccessPolicy(currentAccessPolicy());
714 
715  ret->setClassType(classType);
716  return ret;
717}
718
719Declaration* DeclarationBuilder::openDefinition(NameAST* name, AST* rangeNode, bool collapseRange)
720{
721  Declaration* ret = openNormalDeclaration(name, rangeNode, KDevelop::Identifier(), collapseRange);
722 
723  ///Create mappings iff the AST feature is specified
724  if(m_mapAst && !m_mappedNodes.empty())
725    editor()->parseSession()->mapAstDuChain(m_mappedNodes.top(), KDevelop::DeclarationPointer(ret));
726
727  DUChainWriteLocker lock(DUChain::lock());
728  ret->setDeclarationIsDefinition(true);
729  return ret;
730}
731
732Declaration* DeclarationBuilder::openNormalDeclaration(NameAST* name, AST* rangeNode, const Identifier& customName, bool collapseRange) {
733  if(currentContext()->type() == DUContext::Class) {
734    ClassMemberDeclaration* mem = openDeclaration<ClassMemberDeclaration>(name, rangeNode, customName, collapseRange);
735
736    DUChainWriteLocker lock(DUChain::lock());
737    mem->setAccessPolicy(currentAccessPolicy());
738    return mem;
739  } else if(currentContext()->type() == DUContext::Template) {
740    return openDeclaration<TemplateParameterDeclaration>(name, rangeNode, customName, collapseRange);
741  } else {
742    return openDeclaration<Declaration>(name, rangeNode, customName, collapseRange);
743  }
744}
745
746Declaration* DeclarationBuilder::openFunctionDeclaration(NameAST* name, AST* rangeNode) {
747
748   QualifiedIdentifier id;
749   identifierForNode(name, id);
750   Identifier localId = id.last(); //This also copies the template arguments
751   if(id.count() > 1) {
752     //Merge the scope of the declaration, and put them tog. Add semicolons instead of the ::, so you can see it's not a qualified identifier.
753     //Else the declarations could be confused with global functions.
754     //This is done before the actual search, so there are no name-clashes while searching the class for a constructor.
755
756     QString newId = id.last().identifier().str();
757     for(int a = id.count()-2; a >= 0; --a)
758       newId = id.at(a).identifier().str() + "::" + newId;
759
760     localId.setIdentifier(newId);
761
762     FunctionDefinition* ret = openDeclaration<FunctionDefinition>(name, rangeNode, localId);
763     DUChainWriteLocker lock(DUChain::lock());
764     ret->setDeclaration(0);
765     return ret;
766   }
767
768  if(currentContext()->type() == DUContext::Class) {
769    DUChainWriteLocker lock;
770    ClassFunctionDeclaration* fun = 0;
771    if(!m_collectQtFunctionSignature) {
772      fun = openDeclaration<ClassFunctionDeclaration>(name, rangeNode, localId);
773    }else{
774      QtFunctionDeclaration* qtFun = openDeclaration<QtFunctionDeclaration>(name, rangeNode, localId);
775      fun = qtFun;
776      qtFun->setIsSlot(m_accessPolicyStack.top() & FunctionIsSlot);
777      qtFun->setIsSignal(m_accessPolicyStack.top() & FunctionIsSignal);
778      QByteArray temp(QMetaObject::normalizedSignature("(" + m_qtFunctionSignature + ")"));
779      IndexedString signature(temp.mid(1, temp.length()-2));
780//       kDebug() << "normalized signature:" << signature.str() << "from:" << QString::fromUtf8(m_qtFunctionSignature);
781      qtFun->setNormalizedSignature(signature);
782    }
783    Q_ASSERT(fun);
784    fun->setAccessPolicy(currentAccessPolicy());
785    fun->setIsAbstract(m_functionFlag == AbstractFunction);
786    return fun;
787  } else if(m_inFunctionDefinition && (currentContext()->type() == DUContext::Namespace || currentContext()->type() == DUContext::Global)) {
788    //May be a definition
789     FunctionDefinition* ret = openDeclaration<FunctionDefinition>(name, rangeNode, localId);
790     DUChainWriteLocker lock(DUChain::lock());
791     ret->setDeclaration(0);
792     return ret;
793  }else{
794    return openDeclaration<FunctionDeclaration>(name, rangeNode, localId);
795  }
796}
797
798void DeclarationBuilder::classTypeOpened(AbstractType::Ptr type) {
799  //We override this so we can get the class-declaration into a usable state(with filled type) earlier
800    DUChainWriteLocker lock(DUChain::lock());
801
802    IdentifiedType* idType = dynamic_cast<IdentifiedType*>(type.unsafeData());
803
804    if( idType && !idType->declarationId().isValid() ) //When the given type has no declaration yet, assume we are declaring it now
805        idType->setDeclaration( currentDeclaration() );
806
807    currentDeclaration()->setType(type);
808}
809
810void DeclarationBuilder::closeDeclaration(bool forceInstance)
811{
812  {
813    DUChainWriteLocker lock(DUChain::lock());
814     
815    if (lastType()) {
816
817      AbstractType::Ptr type = typeForCurrentDeclaration();
818      IdentifiedType* idType = dynamic_cast<IdentifiedType*>(type.unsafeData());
819      DelayedType::Ptr delayed = type.cast<DelayedType>();
820
821      //When the given type has no declaration yet, assume we are declaring it now.
822      //If the type is a delayed type, it is a searched type, and not a declared one, so don't set the declaration then.
823      if( !forceInstance && idType && !idType->declarationId().isValid() && !delayed ) {
824          idType->setDeclaration( currentDeclaration() );
825          //Q_ASSERT(idType->declaration() == currentDeclaration());
826      }
827
828      if(currentDeclaration()->kind() != Declaration::NamespaceAlias && currentDeclaration()->kind() != Declaration::Alias) {
829        //If the type is not identified, it is an instance-declaration too, because those types have no type-declarations.
830        if( (((!idType) || (idType && idType->declarationId() != currentDeclaration()->id())) && !currentDeclaration()->isTypeAlias() && !currentDeclaration()->isForwardDeclaration() ) || dynamic_cast<AbstractFunctionDeclaration*>(currentDeclaration()) || forceInstance )
831          currentDeclaration()->setKind(Declaration::Instance);
832        else
833          currentDeclaration()->setKind(Declaration::Type);
834      }
835
836      currentDeclaration()->setType(type);
837    }else{
838      currentDeclaration()->setAbstractType(AbstractType::Ptr());
839      if(dynamic_cast<ClassDeclaration*>(currentDeclaration()))
840        currentDeclaration()->setKind(Declaration::Type);
841    }
842    if(TemplateDeclaration* templateDecl = dynamic_cast<TemplateDeclaration*>(currentDeclaration())) {
843      //The context etc. may have been filled with new items, and the declaration may have been searched unsuccessfully, or wrong instantiations created.
844      TemplateDeclaration* deleteInstantiationsOf = 0;
845      if(templateDecl->instantiatedFrom())
846        deleteInstantiationsOf = templateDecl->instantiatedFrom();
847      else if(templateDecl->specializedFrom().data())
848        deleteInstantiationsOf = dynamic_cast<TemplateDeclaration*>(templateDecl->specializedFrom().data());
849      else
850        deleteInstantiationsOf = templateDecl;
851     
852      if(deleteInstantiationsOf) {
853        CppDUContext<DUContext>* ctx = dynamic_cast<CppDUContext<DUContext>*>(dynamic_cast<Declaration*>(deleteInstantiationsOf)->internalContext());
854        deleteInstantiationsOf->deleteAllInstantiations();
855        if(ctx)
856          ctx->deleteAllInstantiations();
857      }
858    }
859  }
860
861  if(lastContext() && (lastContext()->type() != DUContext::Other || currentDeclaration()->isFunctionDeclaration()))
862    eventuallyAssignInternalContext();
863
864  ifDebugCurrentFile( DUChainReadLocker lock(DUChain::lock()); kDebug() << "closing declaration" << currentDeclaration()->toString() << "type" << (currentDeclaration()->abstractType() ? currentDeclaration()->abstractType()->toString() : QString("notype")) << "last:" << (lastType() ? lastType()->toString() : QString("(notype)")); )
865
866  m_lastDeclaration = m_declarationStack.pop();
867}
868
869void DeclarationBuilder::visitTypedef(TypedefAST *def)
870{
871  parseComments(def->comments);
872
873  DeclarationBuilderBase::visitTypedef(def);
874}
875
876void DeclarationBuilder::visitEnumSpecifier(EnumSpecifierAST* node)
877{
878  Declaration * declaration = 0;
879  if (!node->isOpaque) {
880    declaration = openDefinition(node->name, node, node->name == 0);
881  } else {
882    // opaque-enum-declaration
883    declaration = openForwardDeclaration(node->name, node);
884  }
885
886  ///Create mappings iff the AST feature is specified
887  if(m_mapAst)
888    editor()->parseSession()->mapAstDuChain(node, KDevelop::DeclarationPointer(declaration));
889
890  DeclarationBuilderBase::visitEnumSpecifier(node);
891
892  closeDeclaration();
893}
894
895///Replaces a CppTemplateParameterType with a DelayedType
896struct TemplateTypeExchanger : public KDevelop::TypeExchanger {
897
898  TemplateTypeExchanger(TopDUContext* top) : m_top(top) {
899  }
900
901  virtual AbstractType::Ptr exchange( const AbstractType::Ptr& type )
902  {
903    if(CppTemplateParameterType::Ptr templateParamType = type.cast<CppTemplateParameterType>()) {
904      Declaration* decl = templateParamType->declaration(m_top);
905      if(decl) {
906        DelayedType::Ptr newType(new DelayedType());
907       
908        IndexedTypeIdentifier id(QualifiedIdentifier(decl->identifier()));
909       
910        if(type->modifiers() & AbstractType::ConstModifier)
911            id.setIsConstant(true);
912           
913        newType->setIdentifier(id);
914        newType->setKind(KDevelop::DelayedType::Delayed);
915       
916        return newType.cast<AbstractType>();
917      }
918    }
919    return type;
920  }
921  private:
922    TopDUContext* m_top;
923};
924
925Cpp::InstantiationInformation DeclarationBuilder::createSpecializationInformation(Cpp::InstantiationInformation base, UnqualifiedNameAST* name, KDevelop::DUContext* templateContext) {
926    if(name->template_arguments || base.isValid()) 
927    {
928      //Append a scope part
929      InstantiationInformation newCurrent;
930      newCurrent.previousInstantiationInformation = base.indexed();
931      if(!name->template_arguments)
932        return newCurrent;
933      //Process the template arguments if they exist
934      const ListNode<TemplateArgumentAST*> * start = name->template_arguments->toFront();
935      const ListNode<TemplateArgumentAST*> * current = start;
936      do {
937        NameASTVisitor visitor(editor()->parseSession(), 0, templateContext, currentContext()->topContext(), templateContext, templateContext->range().end/*, DUContext::NoUndefinedTemplateParams*/);
938        ExpressionEvaluationResult res = visitor.processTemplateArgument(current->element);
939        AbstractType::Ptr type = res.type.abstractType();
940       
941        TemplateTypeExchanger exchanger(currentContext()->topContext());
942       
943        if(type) {
944          type = exchanger.exchange(type);
945          type->exchangeTypes(&exchanger);
946        }
947       
948        newCurrent.addTemplateParameter(type);
949
950        current = current->next;
951      }while(current != start);
952      return newCurrent;
953    }else{
954      return base;
955    }
956}
957
958Cpp::IndexedInstantiationInformation DeclarationBuilder::createSpecializationInformation(NameAST* name, DUContext* templateContext)
959{
960  InstantiationInformation currentInfo;
961  if(name->qualified_names) {
962    const ListNode<UnqualifiedNameAST*> * start = name->qualified_names->toFront();
963    const ListNode<UnqualifiedNameAST*> * current = start;
964    do {
965      currentInfo = createSpecializationInformation(currentInfo, current->element, templateContext);
966      current = current->next;
967    }while(current != start);
968  }
969  if(name->unqualified_name)
970    currentInfo = createSpecializationInformation(currentInfo, name->unqualified_name, templateContext);
971  return currentInfo.indexed();
972}
973
974void DeclarationBuilder::visitEnumerator(EnumeratorAST* node)
975{
976  //Ugly hack: Since we want the identifier only to have the range of the id(not
977  //the assigned expression), we change the range of the node temporarily
978  uint oldEndToken = node->end_token;
979  node->end_token = node->id + 1;
980
981  Identifier id(editor()->parseSession()->token_stream->token(node->id).symbol());
982  Declaration* decl = openNormalDeclaration(0, node, id);
983
984  node->end_token = oldEndToken;
985
986  DeclarationBuilderBase::visitEnumerator(node);
987
988  EnumeratorType::Ptr enumeratorType = lastType().cast<EnumeratorType>();
989
990  if(ClassMemberDeclaration* classMember = dynamic_cast<ClassMemberDeclaration*>(currentDeclaration())) {
991    DUChainWriteLocker lock(DUChain::lock());
992    classMember->setStatic(true);
993  }
994
995  closeDeclaration(true);
996
997  if(enumeratorType) { ///@todo Move this into closeDeclaration in a logical way
998    DUChainWriteLocker lock(DUChain::lock());
999    enumeratorType->setDeclaration(decl);
1000    decl->setAbstractType(enumeratorType.cast<AbstractType>());
1001  }else if(!lastType().cast<DelayedType>()){ //If it's in a template, it may be DelayedType
1002    AbstractType::Ptr type = lastType();
1003    kWarning() << "not assigned enumerator type:" << typeid(*type.unsafeData()).name() << type->toString();
1004  }
1005}
1006
1007void DeclarationBuilder::classContextOpened(ClassSpecifierAST* /*node*/, DUContext* context) {
1008 
1009  //We need to set this early, so we can do correct search while building
1010  DUChainWriteLocker lock(DUChain::lock());
1011  currentDeclaration()->setInternalContext(context);
1012}
1013
1014void DeclarationBuilder::closeContext()
1015{
1016  if (!m_pendingPropertyDeclarations.isEmpty()) {
1017    if(m_pendingPropertyDeclarations.contains(currentContext()))
1018      resolvePendingPropertyDeclarations(m_pendingPropertyDeclarations.values(currentContext()));
1019  }
1020
1021  DeclarationBuilderBase::closeContext();
1022}
1023
1024void DeclarationBuilder::visitNamespace(NamespaceAST* ast) {
1025
1026  {
1027    RangeInRevision range;
1028    Identifier id;
1029   
1030    if(ast->namespace_name)
1031    {
1032      id = Identifier(editor()->tokensToStrings(ast->namespace_name, ast->namespace_name+1));
1033      range = editor()->findRange(ast->namespace_name, ast->namespace_name+1);
1034    }else
1035    {
1036      id = unnamedNamespaceIdentifier().identifier();
1037      range.start = editor()->findPosition(ast->linkage_body ? ast->linkage_body->start_token : ast->start_token, CppEditorIntegrator::FrontEdge);
1038      range.end = range.start;
1039    }
1040
1041    DUChainWriteLocker lock(DUChain::lock());
1042
1043    Declaration * declaration = openDeclarationReal<Declaration>(0, 0, id, false, false, &range);
1044   
1045    ///Create mappings iff the AST feature is specified
1046    if(m_mapAst)
1047      editor()->parseSession()->mapAstDuChain(ast, KDevelop::DeclarationPointer(declaration));
1048  }
1049 
1050  DeclarationBuilderBase::visitNamespace(ast);
1051 
1052  {
1053    DUChainWriteLocker lock(DUChain::lock());
1054    currentDeclaration()->setKind(KDevelop::Declaration::Namespace);
1055    clearLastType();
1056    closeDeclaration();
1057  }
1058}
1059
1060void DeclarationBuilder::visitClassSpecifier(ClassSpecifierAST *node)
1061{
1062  PushValue<bool> setNotInTypedef(m_inTypedef, false);
1063 
1064  /**Open helper contexts around the class, so the qualified identifier matches.
1065   * Example: "class MyClass::RealClass{}"
1066   * Will create one helper-context named "MyClass" around RealClass
1067   * */
1068
1069  CursorInRevision pos = editor()->findPosition(node->start_token, CppEditorIntegrator::FrontEdge);
1070
1071  IndexedInstantiationInformation specializedWith;
1072 
1073  QualifiedIdentifier id;
1074  if( node->name ) {
1075    identifierForNode(node->name, id);
1076    openPrefixContext(node, id, pos);
1077    DUChainReadLocker lock(DUChain::lock());
1078    if(DUContext* templateContext = hasTemplateContext(m_importedParentContexts, topContext()).context(topContext())) {
1079      specializedWith = createSpecializationInformation(node->name, templateContext);
1080    }
1081  }
1082
1083  int kind = editor()->parseSession()->token_stream->kind(node->class_key);
1084 
1085  ClassDeclaration * declaration = openClassDefinition(node->name, node, node->name == 0, classTypeFromTokenKind(kind));
1086
1087  if (kind == Token_struct || kind == Token_union)
1088    m_accessPolicyStack.push(Declaration::Public);
1089  else
1090    m_accessPolicyStack.push(Declaration::Private);
1091
1092  DeclarationBuilderBase::visitClassSpecifier(node);
1093
1094  eventuallyAssignInternalContext();
1095
1096  if( node->name ) {
1097    ///Copy template default-parameters from the forward-declaration to the real declaration if possible
1098    DUChainWriteLocker lock(DUChain::lock());
1099
1100    QList<Declaration*> declarations = Cpp::findDeclarationsSameLevel(currentContext(), id.last(), pos);
1101
1102    foreach( Declaration* decl, declarations ) {
1103      if( decl->abstractType()) {
1104        ForwardDeclaration* forward =  dynamic_cast<ForwardDeclaration*>(decl);
1105        if( forward ) {
1106          {
1107            KDevelop::DUContext* forwardTemplateContext = forward->internalContext();
1108            if( forwardTemplateContext && forwardTemplateContext->type() == DUContext::Template ) {
1109
1110              KDevelop::DUContext* currentTemplateContext = getTemplateContext(currentDeclaration());
1111              if( (bool)forwardTemplateContext != (bool)currentTemplateContext ) {
1112                kDebug(9007) << "Template-contexts of forward- and real declaration do not match: " << currentTemplateContext << getTemplateContext(currentDeclaration()) << currentDeclaration()->internalContext() << forwardTemplateContext << currentDeclaration()->internalContext()->importedParentContexts().count();
1113              } else if( forwardTemplateContext && currentTemplateContext ) {
1114                if( forwardTemplateContext->localDeclarations().count() != currentTemplateContext->localDeclarations().count() ) {
1115                } else {
1116
1117                  const QVector<Declaration*>& forwardList = forwardTemplateContext->localDeclarations();
1118                  const QVector<Declaration*>& realList = currentTemplateContext->localDeclarations();
1119
1120                  QVector<Declaration*>::const_iterator forwardIt = forwardList.begin();
1121                  QVector<Declaration*>::const_iterator realIt = realList.begin();
1122
1123                  for( ; forwardIt != forwardList.end(); ++forwardIt, ++realIt ) {
1124                    TemplateParameterDeclaration* forwardParamDecl = dynamic_cast<TemplateParameterDeclaration*>(*forwardIt);
1125                    TemplateParameterDeclaration* realParamDecl = dynamic_cast<TemplateParameterDeclaration*>(*realIt);
1126                    if( forwardParamDecl && realParamDecl ) {
1127                      if( !forwardParamDecl->defaultParameter().isEmpty() )
1128                        realParamDecl->setDefaultParameter(forwardParamDecl->defaultParameter());
1129                    }
1130                  }
1131                }
1132              }
1133            }
1134          }
1135
1136          //Update instantiations in case of template forward-declarations
1137//           SpecialTemplateDeclaration<ForwardDeclaration>* templateForward = dynamic_cast<SpecialTemplateDeclaration<ForwardDeclaration>* > (decl);
1138//           SpecialTemplateDeclaration<Declaration>* currentTemplate = dynamic_cast<SpecialTemplateDeclaration<Declaration>* >  (currentDeclaration());
1139//
1140//           if( templateForward && currentTemplate )
1141//           {
1142//             //Change the types of all the forward-template instantiations
1143//             TemplateDeclaration::InstantiationsHash instantiations = templateForward->instantiations();
1144//
1145//             for( TemplateDeclaration::InstantiationsHash::iterator it = instantiations.begin(); it != instantiations.end(); ++it )
1146//             {
1147//               Declaration* realInstance = currentTemplate->instantiate(it.key().args, ImportTrace());
1148//               Declaration* forwardInstance = dynamic_cast<Declaration*>(*it);
1149//               //Now change the type of forwardInstance so it matches the type of realInstance
1150//               CppClassType::Ptr realClass = realInstance->type<CppClassType>();
1151//               CppClassType::Ptr forwardClass = forwardInstance->type<CppClassType>();
1152//
1153//               if( realClass && forwardClass ) {
1154//                 //Copy the class from real into the forward-declaration's instance
1155//                 copyCppClass(realClass.data(), forwardClass.data());
1156//               } else {
1157//                 kDebug(9007) << "Bad types involved in formward-declaration";
1158//               }
1159//             }
1160//           }//templateForward && currentTemplate
1161        }
1162      }
1163    }//foreach
1164
1165  }//node-name
1166
1167  TemplateDeclaration* tempDecl = dynamic_cast<TemplateDeclaration*>(currentDeclaration());
1168 
1169  if(tempDecl) {
1170    DUChainWriteLocker lock(DUChain::lock());
1171    tempDecl->setSpecializedWith(specializedWith);
1172  }
1173  closeDeclaration();
1174 
1175  ///Create mappings iff the AST feature is specified
1176  if(m_mapAst)
1177    editor()->parseSession()->mapAstDuChain(node, KDevelop::DeclarationPointer(declaration));
1178 
1179  if(node->name)
1180    closePrefixContext(id);
1181
1182  m_accessPolicyStack.pop();
1183}
1184
1185void DeclarationBuilder::visitBaseSpecifier(BaseSpecifierAST *node) {
1186  DeclarationBuilderBase::visitBaseSpecifier(node);
1187
1188  BaseClassInstance instance;
1189  {
1190    DUChainWriteLocker lock(DUChain::lock());
1191    ClassDeclaration* currentClass = dynamic_cast<ClassDeclaration*>(currentDeclaration());
1192    if(currentClass) {
1193
1194      instance.virtualInheritance = (bool)node->virt;
1195
1196      //TypeUtils::unAliasedType(
1197      instance.baseClass = TypeUtils::unAliasedType(lastType())->indexed();
1198      if(currentClass->classType() == ClassDeclarationData::Struct)
1199        instance.access = KDevelop::Declaration::Public;
1200      else
1201        instance.access = KDevelop::Declaration::Private;
1202
1203      if( node->access_specifier ) {
1204        int tk = editor()->parseSession()->token_stream->token(node->access_specifier).kind;
1205
1206        switch( tk ) {
1207          case Token_private:
1208            instance.access = KDevelop::Declaration::Private;
1209            break;
1210          case Token_public:
1211            instance.access = KDevelop::Declaration::Public;
1212            break;
1213          case Token_protected:
1214            instance.access = KDevelop::Declaration::Protected;
1215            break;
1216        }
1217      }
1218
1219      currentClass->addBaseClass(instance);
1220    }else{
1221      kWarning() << "base-specifier without class declaration";
1222    }
1223  }
1224  addBaseType(instance, node);
1225}
1226
1227QualifiedIdentifier DeclarationBuilder::resolveNamespaceIdentifier(const QualifiedIdentifier& identifier, const CursorInRevision& position)
1228{
1229  QList< Declaration* > decls = currentContext()->findDeclarations(identifier, position);
1230
1231  QList<DUContext*> contexts;
1232
1233  // qlist does not provide convenient stable iterators
1234  for (QList<Declaration*>::iterator it = decls.begin(); it != decls.end(); ++it) {
1235    Declaration * decl = *it;
1236    if(decl->kind() == Declaration::Namespace && decl->internalContext()) {
1237      contexts << decl->internalContext();
1238    } else if (decl->kind() == Declaration::NamespaceAlias) {
1239      NamespaceAliasDeclaration *aliasDecl = dynamic_cast<NamespaceAliasDeclaration*>(decl);
1240      if (aliasDecl) {
1241        QList<Declaration*> importedDecls = currentContext()->findDeclarations(aliasDecl->importIdentifier(), position);
1242        std::copy(importedDecls.begin(), importedDecls.end(),
1243                  std::back_inserter(decls));
1244      }
1245    }
1246  }
1247 
1248  if( contexts.isEmpty() ) {
1249    //Failed to resolve namespace
1250    kDebug(9007) << "Failed to resolve namespace \"" << identifier << "\"";
1251    QualifiedIdentifier ret = identifier;
1252    ret.setExplicitlyGlobal(false);
1253    Q_ASSERT(ret.count());
1254    return ret;
1255  } else {
1256    QualifiedIdentifier ret = contexts.first()->scopeIdentifier(true);
1257    ret.setExplicitlyGlobal(false);
1258    if(ret.isEmpty())
1259        return ret;
1260    Q_ASSERT(ret.count());
1261    return ret;
1262  }
1263}
1264
1265void DeclarationBuilder::visitUsing(UsingAST * node)
1266{
1267  DeclarationBuilderBase::visitUsing(node);
1268
1269  QualifiedIdentifier id;
1270  identifierForNode(node->name, id);
1271
1272  ///@todo only use the last name component as range
1273  AliasDeclaration* decl = openDeclaration<AliasDeclaration>(0, node->name ? (AST*)node->name : (AST*)node, id.last());
1274  {
1275    DUChainWriteLocker lock(DUChain::lock());
1276
1277    CursorInRevision pos = editor()->findPosition(node->start_token, CppEditorIntegrator::FrontEdge);
1278    QList<Declaration*> declarations = currentContext()->findDeclarations(id, pos);
1279    if(!declarations.isEmpty()) {
1280      decl->setAliasedDeclaration(declarations[0]);
1281    }else{
1282      kDebug(9007) << "Aliased declaration not found:" << id.toString();
1283    }
1284
1285    if(m_accessPolicyStack.isEmpty())
1286      decl->setAccessPolicy(KDevelop::Declaration::Public);
1287    else
1288      decl->setAccessPolicy(currentAccessPolicy());
1289  }
1290
1291  closeDeclaration();
1292}
1293
1294void DeclarationBuilder::visitUsingDirective(UsingDirectiveAST * node)
1295{
1296  DeclarationBuilderBase::visitUsingDirective(node);
1297
1298  if( compilingContexts() ) {
1299    RangeInRevision range = editor()->findRange(node->start_token);
1300    DUChainWriteLocker lock(DUChain::lock());
1301    NamespaceAliasDeclaration* decl = openDeclarationReal<NamespaceAliasDeclaration>(0, 0, globalImportIdentifier(), false, false, &range);
1302    {
1303      QualifiedIdentifier id;
1304      identifierForNode(node->name, id);
1305      decl->setImportIdentifier( resolveNamespaceIdentifier(id, currentDeclaration()->range().start) );
1306    }
1307    closeDeclaration();
1308  }
1309}
1310
1311void DeclarationBuilder::visitAliasDeclaration(AliasDeclarationAST* node)
1312{
1313  DeclarationBuilderBase::visitAliasDeclaration(node);
1314
1315  if( compilingContexts() ) {
1316    PushValue<bool> setTypeDef(m_inTypedef, true);
1317    Declaration* decl = openDeclaration<Declaration>(node->name, node->name);
1318    closeDeclaration();
1319  }
1320}
1321
1322void DeclarationBuilder::visitTypeId(TypeIdAST * typeId)
1323{
1324  //TypeIdAST contains a declarator, but that one does not declare anything
1325  PushValue<bool> disableDeclarators(m_ignoreDeclarators, true);
1326 
1327  DeclarationBuilderBase::visitTypeId(typeId);
1328}
1329
1330void DeclarationBuilder::visitNamespaceAliasDefinition(NamespaceAliasDefinitionAST* node)
1331{
1332  DeclarationBuilderBase::visitNamespaceAliasDefinition(node);
1333
1334  {
1335    DUChainReadLocker lock(DUChain::lock());
1336    if( currentContext()->type() != DUContext::Namespace && currentContext()->type() != DUContext::Global ) {
1337      ///@todo report problem
1338      kDebug(9007) << "Namespace-alias used in non-global scope";
1339    }
1340  }
1341
1342  if( compilingContexts() ) {
1343    RangeInRevision range = editor()->findRange(node->namespace_name);
1344    DUChainWriteLocker lock(DUChain::lock());
1345    NamespaceAliasDeclaration* decl = openDeclarationReal<NamespaceAliasDeclaration>(0, 0, Identifier(editor()->parseSession()->token_stream->token(node->namespace_name).symbol()), false, false, &range);
1346    {
1347      QualifiedIdentifier id;
1348      identifierForNode(node->alias_name, id);
1349      decl->setImportIdentifier( resolveNamespaceIdentifier(id, currentDeclaration()->range().start) );
1350    }
1351    closeDeclaration();
1352  }
1353}
1354
1355void DeclarationBuilder::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST* node)
1356{
1357  PushValue<bool> setNotInTypedef(m_inTypedef, false);
1358 
1359  int kind = editor()->parseSession()->token_stream->kind(node->type);
1360
1361  if( kind == Token_typename ) {
1362    //typename is completely handled by the type-builder
1363    DeclarationBuilderBase::visitElaboratedTypeSpecifier(node);
1364    return;
1365  }
1366 
1367  bool isFriendDeclaration = !m_storageSpecifiers.isEmpty() && (m_storageSpecifiers.top() & ClassMemberDeclaration::FriendSpecifier);
1368
1369  bool openedDeclaration = false;
1370
1371  if (node->name) {
1372    QualifiedIdentifier id;
1373    identifierForNode(node->name, id);
1374
1375    bool forwardDeclarationGlobal = false;
1376
1377    if(m_typeSpecifierWithoutInitDeclarators != node->start_token || isFriendDeclaration) {
1378      /**This is an elaborated type-specifier
1379       *
1380       * See iso c++ draft 3.3.4 for details.
1381       * Said shortly it means:
1382       * - Search for an existing declaration of the type. If it is found,
1383       *   it will be used, and we don't need to create a declaration.
1384       * - If it is not found, create a forward-declaration in the global/namespace scope.
1385       * - @todo While searching for the existing declarations, non-fitting overloaded names should be ignored.
1386       * */
1387
1388      ///@todo think how this interacts with re-using duchains. In some cases a forward-declaration should still be created.
1389      QList<Declaration*> declarations;
1390      CursorInRevision pos = editor()->findPosition(node->start_token, CppEditorIntegrator::FrontEdge);
1391
1392      {
1393        DUChainReadLocker lock(DUChain::lock());
1394
1395        declarations = currentContext()->findDeclarations( id, pos);
1396
1397        forwardDeclarationGlobal = true;
1398       
1399        //If a good declaration has been found, use its type. Else, create a new forward-declaration.
1400        foreach(Declaration* decl, declarations)
1401        {
1402          if((decl->topContext() != currentContext()->topContext() || wasEncountered(decl)) && decl->abstractType())
1403          {
1404            setLastType(declarations.first()->abstractType());
1405           
1406            if( isFriendDeclaration ) {
1407              lock.unlock();
1408              createFriendDeclaration(node);
1409            }
1410            return;
1411          }
1412        }
1413      }
1414    }
1415
1416    node->isDeclaration = true;
1417
1418    // Create forward declaration
1419    switch (kind) {
1420      case Token_class:
1421      case Token_struct:
1422      case Token_union:
1423      case Token_enum:
1424
1425        if(forwardDeclarationGlobal) {
1426          //Open the global context, so it is currentContext() and we can insert the forward-declaration there
1427          DUContext* globalCtx;
1428          {
1429            DUChainReadLocker lock(DUChain::lock());
1430            globalCtx = currentContext();
1431            while(globalCtx && globalCtx->type() != DUContext::Global && globalCtx->type() != DUContext::Namespace)
1432              globalCtx = globalCtx->parentContext();
1433            Q_ASSERT(globalCtx);
1434          }
1435
1436          //Just temporarily insert the new context
1437          injectContext( globalCtx );
1438        }
1439
1440        openForwardDeclaration(node->name, node);
1441
1442        if(forwardDeclarationGlobal) {
1443          closeInjectedContext();
1444        }
1445
1446        openedDeclaration = true;
1447        break;
1448    }
1449  }
1450
1451  DeclarationBuilderBase::visitElaboratedTypeSpecifier(node);
1452
1453  if (openedDeclaration) {
1454/*    DUChainWriteLocker lock(DUChain::lock());
1455    //Resolve forward-declarations that are declared after the real type was already declared
1456    Q_ASSERT(dynamic_cast<ForwardDeclaration*>(currentDeclaration()));
1457    IdentifiedType* idType = dynamic_cast<IdentifiedType*>(lastType().data());
1458    if(idType && idType->declaration())
1459      static_cast<ForwardDeclaration*>(currentDeclaration())->setResolved(idType->declaration());*/
1460    closeDeclaration();
1461  }
1462 
1463  if( isFriendDeclaration )
1464    createFriendDeclaration(node);
1465}
1466
1467void DeclarationBuilder::createFriendDeclaration(AST* range) {
1468  static IndexedIdentifier friendIdentifier(Identifier("friend"));
1469  openDeclaration<Declaration>(0, range, friendIdentifier.identifier(), true);
1470  closeDeclaration();
1471}
1472
1473void DeclarationBuilder::visitAccessSpecifier(AccessSpecifierAST* node)
1474{
1475  bool isSlot = false;
1476  bool isSignal = false;
1477  if (node->specs) {
1478    const ListNode<uint> *it = node->specs->toFront();
1479    const ListNode<uint> *end = it;
1480    do {
1481      int kind = editor()->parseSession()->token_stream->kind(it->element);
1482      switch (kind) {
1483        case Token___qt_slots__:
1484        case Token_k_dcop:
1485          isSlot = true;
1486          break;
1487        case Token_public:
1488          setAccessPolicy(Declaration::Public);
1489          break;
1490        case Token_k_dcop_signals:
1491        case Token___qt_signals__:
1492          isSignal = true;
1493        case Token_protected:
1494          setAccessPolicy(Declaration::Protected);
1495          break;
1496        case Token_private:
1497          setAccessPolicy(Declaration::Private);
1498          break;
1499      }
1500
1501      it = it->next;
1502    } while (it != end);
1503  }
1504 
1505  if(isSignal)
1506    setAccessPolicy((KDevelop::Declaration::AccessPolicy)(currentAccessPolicy() | FunctionIsSignal));
1507
1508  if(isSlot)
1509    setAccessPolicy((KDevelop::Declaration::AccessPolicy)(currentAccessPolicy() | FunctionIsSlot));
1510 
1511
1512  DeclarationBuilderBase::visitAccessSpecifier(node);
1513}
1514
1515void DeclarationBuilder::parseStorageSpecifiers(const ListNode<uint>* storage_specifiers)
1516{
1517  ClassMemberDeclaration::StorageSpecifiers specs = 0;
1518
1519  if (storage_specifiers) {
1520    const ListNode<uint> *it = storage_specifiers->toFront();
1521    const ListNode<uint> *end = it;
1522    do {
1523      int kind = editor()->parseSession()->token_stream->kind(it->element);
1524      switch (kind) {
1525        case Token_friend:
1526          specs |= ClassMemberDeclaration::FriendSpecifier;
1527          break;
1528        case Token_auto:
1529          specs |= ClassMemberDeclaration::AutoSpecifier;
1530          break;
1531        case Token_register:
1532          specs |= ClassMemberDeclaration::RegisterSpecifier;
1533          break;
1534        case Token_static:
1535          specs |= ClassMemberDeclaration::StaticSpecifier;
1536          break;
1537        case Token_extern:
1538          specs |= ClassMemberDeclaration::ExternSpecifier;
1539          break;
1540        case Token_mutable:
1541          specs |= ClassMemberDeclaration::MutableSpecifier;
1542          break;
1543      }
1544
1545      it = it->next;
1546    } while (it != end);
1547  }
1548
1549  m_storageSpecifiers.push(specs);
1550}
1551
1552void DeclarationBuilder::parseFunctionSpecifiers(const ListNode<uint>* function_specifiers)
1553{
1554  AbstractFunctionDeclaration::FunctionSpecifiers specs = 0;
1555
1556  if (function_specifiers) {
1557    const ListNode<uint> *it = function_specifiers->toFront();
1558    const ListNode<uint> *end = it;
1559    do {
1560      int kind = editor()->parseSession()->token_stream->kind(it->element);
1561      switch (kind) {
1562        case Token_inline:
1563          specs |= AbstractFunctionDeclaration::InlineSpecifier;
1564          break;
1565        case Token_virtual:
1566          specs |= AbstractFunctionDeclaration::VirtualSpecifier;
1567          break;
1568        case Token_explicit:
1569          specs |= AbstractFunctionDeclaration::ExplicitSpecifier;
1570          break;
1571      }
1572
1573      it = it->next;
1574    } while (it != end);
1575  }
1576
1577  m_functionSpecifiers.push(specs);
1578}
1579
1580void DeclarationBuilder::visitParameterDeclaration(ParameterDeclarationAST* node)
1581{
1582  if(m_mapAst)
1583    m_mappedNodes.push(node);
1584 
1585  DeclarationBuilderBase::visitParameterDeclaration(node);
1586 
1587  AbstractFunctionDeclaration* function = currentDeclaration<AbstractFunctionDeclaration>();
1588
1589  if( function ) {
1590   
1591    if( node->expression ) {
1592      DUChainWriteLocker lock(DUChain::lock());
1593      //Fill default-parameters
1594      QString defaultParam = stringFromSessionTokens( editor()->parseSession(), node->expression->start_token, node->expression->end_token ).trimmed();
1595
1596      function->addDefaultParameter(IndexedString(defaultParam));
1597    }
1598    if( !node->declarator ) {
1599      //If there is no declarator, still create a declaration
1600      openDefinition(0, node, true);
1601      closeDeclaration();
1602    }
1603  }
1604 
1605  if(m_mapAst)
1606    m_mappedNodes.pop();
1607}
1608
1609void DeclarationBuilder::popSpecifiers()
1610{
1611  m_functionSpecifiers.pop();
1612  m_storageSpecifiers.pop();
1613}
1614
1615void DeclarationBuilder::applyStorageSpecifiers()
1616{
1617  if (!m_storageSpecifiers.isEmpty() && m_storageSpecifiers.top() != 0)
1618    if (ClassMemberDeclaration* member = dynamic_cast<ClassMemberDeclaration*>(currentDeclaration())) {
1619      DUChainWriteLocker lock(DUChain::lock());
1620
1621      member->setStorageSpecifiers(m_storageSpecifiers.top());
1622    }
1623}
1624
1625void DeclarationBuilder::applyFunctionSpecifiers()
1626{
1627  DUChainWriteLocker lock(DUChain::lock());
1628  AbstractFunctionDeclaration* function = dynamic_cast<AbstractFunctionDeclaration*>(currentDeclaration());
1629  if(!function)
1630    return;
1631 
1632  if (!m_functionSpecifiers.isEmpty() && m_functionSpecifiers.top() != 0) {
1633
1634    function->setFunctionSpecifiers(m_functionSpecifiers.top());
1635  }else{
1636    function->setFunctionSpecifiers((AbstractFunctionDeclaration::FunctionSpecifiers)0);
1637  }
1638 
1639  ///Eventually inherit the "virtual" flag from overridden functions
1640  ClassFunctionDeclaration* classFunDecl = dynamic_cast<ClassFunctionDeclaration*>(function);
1641  if(classFunDecl && !classFunDecl->isVirtual()) {
1642    QList<Declaration*> overridden;
1643    foreach(const DUContext::Import &import, currentContext()->importedParentContexts()) {
1644      DUContext* iContext = import.context(topContext());
1645      if(iContext) {
1646        overridden += iContext->findDeclarations(QualifiedIdentifier(classFunDecl->identifier()),
1647                                            CursorInRevision::invalid(), classFunDecl->abstractType(), classFunDecl->topContext(), DUContext::DontSearchInParent);
1648      }
1649    }
1650    if(!overridden.isEmpty()) {
1651      foreach(Declaration* decl, overridden) {
1652        if(AbstractFunctionDeclaration* fun = dynamic_cast<AbstractFunctionDeclaration*>(decl))
1653          if(fun->isVirtual())
1654            classFunDecl->setVirtual(true);
1655      }
1656    }
1657  }
1658}
1659
1660bool DeclarationBuilder::checkParameterDeclarationClause(ParameterDeclarationClauseAST* clause)
1661{
1662    {
1663      DUChainReadLocker lock(DUChain::lock());
1664      if(currentContext()->type() == DUContext::Other) //Cannot declare a function in a code-context
1665        return false; ///@todo create warning/error
1666    }
1667    if(!clause || !clause->parameter_declarations)
1668      return true;
1669    AbstractType::Ptr oldLastType = lastType();
1670
1671    const ListNode<ParameterDeclarationAST*> *start = clause->parameter_declarations->toFront();
1672
1673    const ListNode<ParameterDeclarationAST*> *it = start;
1674
1675    bool ret = false;
1676
1677    do {
1678      ParameterDeclarationAST* ast = it->element;
1679      if(ast) {
1680        if(m_collectQtFunctionSignature) {
1681          uint endToken = ast->end_token;
1682         
1683          if(ast->type_specifier)
1684            endToken = ast->type_specifier->end_token;
1685          if(ast->declarator) {
1686            if(ast->declarator->id)
1687              endToken = ast->declarator->id->start_token;
1688            else
1689              endToken = ast->declarator->end_token;
1690          }
1691         
1692          if(!m_qtFunctionSignature.isEmpty())
1693            m_qtFunctionSignature += ", ";
1694         
1695          m_qtFunctionSignature += editor()->tokensToByteArray(ast->start_token, endToken);
1696          ret = true;
1697        }else{
1698        if(ast->expression || ast->declarator) {
1699          ret = true; //If one parameter has a default argument or a parameter name, it is surely a parameter
1700          break;
1701        }
1702
1703        visit(ast->type_specifier);
1704        if( lastType() ) {
1705          //Break on the first valid thing found
1706          if( lastTypeWasInstance() ) {
1707            ret = false;
1708            break;
1709          }else if(lastType().cast<DelayedType>() && lastType().cast<DelayedType>()->kind() == DelayedType::Unresolved) {
1710            //When the searched item was not found, expect it to be a non-type
1711            ret = false;
1712          }else{
1713            ret = true;
1714            break;
1715          }
1716        }
1717        }
1718      }
1719      it = it->next;
1720    } while (it != start);
1721
1722    setLastType(oldLastType);
1723
1724    return ret;
1725}
1726
1727/// Set the internal context of a declaration; for example, a class declaration's internal context
1728/// is the context inside the brackets: class ClassName { ... }
1729void DeclarationBuilder::eventuallyAssignInternalContext()
1730{
1731  if (TypeBuilder::lastContext()) {
1732    DUChainWriteLocker lock(DUChain::lock());
1733
1734    if( dynamic_cast<ClassFunctionDeclaration*>(currentDeclaration()) )
1735      Q_ASSERT( !static_cast<ClassFunctionDeclaration*>(currentDeclaration())->isConstructor() || currentDeclaration()->context()->type() == DUContext::Class );
1736
1737    if(TypeBuilder::lastContext() && 
1738      (TypeBuilder::lastContext()->type() == DUContext::Class || 
1739        TypeBuilder::lastContext()->type() == DUContext::Other || 
1740        TypeBuilder::lastContext()->type() == DUContext::Function || 
1741        TypeBuilder::lastContext()->type() == DUContext::Template || 
1742        TypeBuilder::lastContext()->type() == DUContext::Enum ||
1743        (TypeBuilder::lastContext()->type() == DUContext::Namespace && currentDeclaration()->kind() == Declaration::Namespace)
1744        ) )
1745    {
1746      if( !TypeBuilder::lastContext()->owner() || !TypeBuilder::wasEncountered(TypeBuilder::lastContext()->owner()) ) { //if the context is already internalContext of another declaration, leave it alone
1747        currentDeclaration()->setInternalContext(TypeBuilder::lastContext());
1748
1749        TypeBuilder::clearLastContext();
1750      }
1751    }
1752  }
1753}