1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/* This file is part of KDevelop
Copyright 2006 Hamish Rodda <rodda@kde.org>
Copyright 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef DECLARATIONBUILDER_H
#define DECLARATIONBUILDER_H
#include "typebuilder.h"
#include <language/duchain/builders/abstractdeclarationbuilder.h>
#include "cppduchainexport.h"
#include <language/duchain/declaration.h>
#include <language/duchain/duchainpointer.h>
#include <language/duchain/classfunctiondeclaration.h>
#include <language/duchain/classdeclaration.h>
namespace Cpp
{
class QPropertyDeclaration;
}
namespace KDevelop
{
class Declaration;
class ClassDeclaration;
}
//Additional flags put into the access-policy member
enum SignalSlotFlags {
FunctionIsSignal = 1 << 4,
FunctionIsSlot = 1 << 5
};
typedef TypeBuilder DeclarationBuilderBase;
/**
* A class which iterates the AST to extract definitions of types.
*/
class KDEVCPPDUCHAIN_EXPORT DeclarationBuilder: public DeclarationBuilderBase
{
public:
DeclarationBuilder(ParseSession* session);
/**
* Compile either a context-definition chain, or add uses to an existing
* chain.
*
* The returned context will have the TopDUContext::UpdatingContext flag set.
*
* \param includes contexts to reference from the top context. The list may be changed by this function.
*/
KDevelop::ReferencedTopDUContext buildDeclarations(Cpp::EnvironmentFilePointer file, AST *node, IncludeFileList* includes = 0, const ReferencedTopDUContext& updateContext = ReferencedTopDUContext(), bool removeOldImports = true);
/**
* Build.an independent du-context based on a given parent-context. Such a context may be used for expression-parsing,
* but should be deleted as fast as possible because it keeps a reference to an independent context.
*
* \param url A temporary url that can be used to identify this context
*
* \param parent Context that will be used as parent for this context
*/
// KDevelop::DUContext* buildSubDeclarations(const IndexedString& url, AST *node, KDevelop::DUContext* parent = 0);
bool changeWasSignificant() const;
protected:
virtual void visitDeclarator (DeclaratorAST*);
virtual void visitNamespace(NamespaceAST* );
virtual void visitClassSpecifier(ClassSpecifierAST*);
virtual void visitBaseSpecifier(BaseSpecifierAST *node);
virtual void visitAccessSpecifier(AccessSpecifierAST*);
virtual void visitFunctionDeclaration(FunctionDefinitionAST*);
virtual void visitSimpleDeclaration(SimpleDeclarationAST*);
virtual void visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST*);
virtual void visitParameterDeclaration(ParameterDeclarationAST* node);
virtual void visitTypedef(TypedefAST *);
virtual void visitTemplateParameter(TemplateParameterAST *);
virtual void visitUsingDirective(UsingDirectiveAST *);
virtual void visitUsing(UsingAST *);
virtual void visitEnumSpecifier(EnumSpecifierAST*);
virtual void visitEnumerator(EnumeratorAST* node);
virtual void visitNamespaceAliasDefinition(NamespaceAliasDefinitionAST*);
virtual void visitTypeId(TypeIdAST *);
virtual void visitInitDeclarator(InitDeclaratorAST *node);
virtual void visitQPropertyDeclaration(QPropertyDeclarationAST *);
virtual void visitForRangeDeclaration(ForRangeDeclarationAst *node);
virtual void visitAliasDeclaration(AliasDeclarationAST* );
virtual void classTypeOpened(KDevelop::AbstractType::Ptr);
virtual void classContextOpened(ClassSpecifierAST *node, DUContext* context);
virtual void closeContext();
private:
//Returns true if the given parameter declaration clause is really a parameter declaration clause, depending on the given parameters.
//Also collects the Qt function signature if required. In that case, true is always returned.
bool checkParameterDeclarationClause(ParameterDeclarationClauseAST* clause);
//Du-chain must be locked
QualifiedIdentifier resolveNamespaceIdentifier(const QualifiedIdentifier& identifier, const KDevelop::CursorInRevision& position);
KDevelop::ForwardDeclaration* openForwardDeclaration(NameAST* name, AST* range);
/**
* Register a new declaration with the definition-use chain.
* Returns the new context created by this definition.
* @param name When this is zero, the identifier given through customName is used.
* @param range provide a valid AST here if name is null
* @param collapseRange If this is true, the end of the computed range will be moved to the start, so it's empty
*/
template<class T>
T* openDeclaration(NameAST* name, AST* range, const Identifier& customName = Identifier(), bool collapseRange = false, bool collapseRangeAtEnd = false);
template<class T>
T* openDeclarationReal(NameAST* name, AST* range, const Identifier& customName, bool collapseRangeAtStart, bool collapseRangeAtEnd, const RangeInRevision* customRange = 0);
/// Same as the above, but sets it as the definition too @param forceInstance when this is true, the declaration is forced to be an instance, not a type declaration,
/// and its assigned identified type will not get the declaration assigned.
virtual void closeDeclaration(bool forceInstance = false);
//Opens a Declaration that has the isDefinition flag set
KDevelop::Declaration* openDefinition(NameAST* name, AST* range, bool collapseRange = false);
//Opens a ClassDeclaration
KDevelop::ClassDeclaration* openClassDefinition(NameAST* name, AST* range, bool collapseRange, KDevelop::ClassDeclarationData::ClassType classType);
//Opens either a ClassFunctionDeclaration, a FunctionDeclaration, or a FunctionDefinition
Declaration* openFunctionDeclaration(NameAST* name, AST* rangeNode);
//Opens either a ClassMemberDeclaration, or a Declaration
Declaration* openNormalDeclaration(NameAST* name, AST* rangeNode, const Identifier& customName = Identifier(), bool collapseRange = false);
void parseStorageSpecifiers(const ListNode<uint>* storage_specifiers);
void parseFunctionSpecifiers(const ListNode<uint>* function_specifiers);
inline KDevelop::Declaration::AccessPolicy currentAccessPolicy() {
if(m_accessPolicyStack.isEmpty())
return KDevelop::Declaration::Public;
else
return ((KDevelop::Declaration::AccessPolicy)((m_accessPolicyStack.top() & (~((uint)FunctionIsSignal))) & (~((uint)FunctionIsSlot))));
}
inline void setAccessPolicy(KDevelop::Declaration::AccessPolicy policy) { m_accessPolicyStack.top() = policy; }
Cpp::InstantiationInformation createSpecializationInformation(Cpp::InstantiationInformation base, UnqualifiedNameAST* name, KDevelop::DUContext* templateContext);
Cpp::IndexedInstantiationInformation createSpecializationInformation(NameAST* name, DUContext* templateContext);
void parseComments(const ListNode<uint> *comments);
void eventuallyAssignInternalContext();
void applyStorageSpecifiers();
void applyFunctionSpecifiers();
void popSpecifiers();
void createFriendDeclaration(AST* range);
QStack<KDevelop::Declaration::AccessPolicy> m_accessPolicyStack;
QStack<KDevelop::AbstractFunctionDeclaration::FunctionSpecifiers> m_functionSpecifiers;
QStack<KDevelop::ClassMemberDeclaration::StorageSpecifiers> m_storageSpecifiers;
QStack<uint> m_functionDefinedStack;
bool m_changeWasSignificant, m_ignoreDeclarators;
enum FunctionFlag {
NoFunctionFlag,
AbstractFunction,
DefaultFunction,
DeleteFunction
};
FunctionFlag m_functionFlag;
//Ast Mapping members
QStack<AST *> m_mappedNodes;
bool m_collectQtFunctionSignature;
QByteArray m_qtFunctionSignature;
// QProperty handling
typedef QPair<Cpp::QPropertyDeclaration*, QPropertyDeclarationAST*> PropertyResolvePair;
QMultiHash<DUContext*, PropertyResolvePair> m_pendingPropertyDeclarations;
KDevelop::IndexedDeclaration resolveMethodName(NameAST *node);
void resolvePendingPropertyDeclarations(const QList<PropertyResolvePair> &pairs);
/// Inherited from AbstractDeclarationBuilder:
inline Declaration* currentDeclaration() const { return m_declarationStack.isEmpty() ? 0 : m_declarationStack.top(); }
/// Access the current declaration, casted to type \a DeclarationType. \returns the current declaration if one exists and is an instance of the given \a DeclarationType.
template<class DeclarationType>
inline DeclarationType* currentDeclaration() const { return m_declarationStack.isEmpty() ? 0 : dynamic_cast<DeclarationType*>(m_declarationStack.top()); }
/// Access the current comment. \returns the current comment, or an empty string if none exists.
inline const QByteArray& comment() const { return m_lastComment; }
/// Set the current \a comment. \param comment the new comment.
inline void setComment(const QByteArray& comment) { m_lastComment = comment; }
/// Clears the current comment.
inline void clearComment() { m_lastComment.clear(); }
private:
QStack<Declaration*> m_declarationStack;
Declaration* m_lastDeclaration;
QByteArray m_lastComment;
};
#endif // DECLARATIONBUILDER_H
|