diff options
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r-- | src/libs/cplusplus/ExpressionUnderCursor.cpp | 1 | ||||
-rw-r--r-- | src/libs/cplusplus/ExpressionUnderCursor.h | 1 | ||||
-rw-r--r-- | src/libs/cplusplus/GenTemplateInstance.cpp | 145 | ||||
-rw-r--r-- | src/libs/cplusplus/GenTemplateInstance.h | 58 | ||||
-rw-r--r-- | src/libs/cplusplus/ResolveExpression.cpp | 171 | ||||
-rw-r--r-- | src/libs/cplusplus/cplusplus-lib.pri | 2 | ||||
-rw-r--r-- | src/libs/cplusplus/pp-engine.cpp | 19 | ||||
-rw-r--r-- | src/libs/cplusplus/pp-engine.h | 5 | ||||
-rw-r--r-- | src/libs/cplusplus/pp-scanner.h | 9 |
9 files changed, 250 insertions, 161 deletions
diff --git a/src/libs/cplusplus/ExpressionUnderCursor.cpp b/src/libs/cplusplus/ExpressionUnderCursor.cpp index 26a2b3a961..995eeace37 100644 --- a/src/libs/cplusplus/ExpressionUnderCursor.cpp +++ b/src/libs/cplusplus/ExpressionUnderCursor.cpp @@ -38,6 +38,7 @@ using namespace CPlusPlus; ExpressionUnderCursor::ExpressionUnderCursor() + : _jumpedComma(false) { } ExpressionUnderCursor::~ExpressionUnderCursor() diff --git a/src/libs/cplusplus/ExpressionUnderCursor.h b/src/libs/cplusplus/ExpressionUnderCursor.h index b72f790f97..faf969662b 100644 --- a/src/libs/cplusplus/ExpressionUnderCursor.h +++ b/src/libs/cplusplus/ExpressionUnderCursor.h @@ -59,6 +59,7 @@ private: int previousBlockState(const QTextBlock &block); bool isAccessToken(const SimpleToken &tk); +private: bool _jumpedComma; }; diff --git a/src/libs/cplusplus/GenTemplateInstance.cpp b/src/libs/cplusplus/GenTemplateInstance.cpp new file mode 100644 index 0000000000..0755593250 --- /dev/null +++ b/src/libs/cplusplus/GenTemplateInstance.cpp @@ -0,0 +1,145 @@ + +#include "GenTemplateInstance.h" +#include <Control.h> +#include <Scope.h> +#include <Names.h> +#include <Symbols.h> +#include <CoreTypes.h> +#include <QtCore/QVarLengthArray> + +using namespace CPlusPlus; + +GenTemplateInstance::GenTemplateInstance(Control *control, const Substitution &substitution) + : _control(control), + _substitution(substitution) +{ } + +FullySpecifiedType GenTemplateInstance::operator()(const FullySpecifiedType &ty) +{ return subst(ty); } + +FullySpecifiedType GenTemplateInstance::subst(Name *name) +{ + if (TemplateNameId *t = name->asTemplateNameId()) { + QVarLengthArray<FullySpecifiedType, 8> args(t->templateArgumentCount()); + + for (unsigned i = 0; i < t->templateArgumentCount(); ++i) + args[i] = subst(t->templateArgumentAt(i)); + + TemplateNameId *n = _control->templateNameId(t->identifier(), + args.data(), args.size()); + + return FullySpecifiedType(_control->namedType(n)); + } else if (name->isQualifiedNameId()) { + // ### implement me + } + + for (int i = 0; i < _substitution.size(); ++i) { + const QPair<Name *, FullySpecifiedType> s = _substitution.at(i); + if (name->isEqualTo(s.first)) + return s.second; + } + + return FullySpecifiedType(_control->namedType(name)); +} + +FullySpecifiedType GenTemplateInstance::subst(const FullySpecifiedType &ty) +{ + FullySpecifiedType previousType = switchType(ty); + TypeVisitor::accept(ty.type()); + return switchType(previousType); +} + +FullySpecifiedType GenTemplateInstance::switchType(const FullySpecifiedType &type) +{ + FullySpecifiedType previousType = _type; + _type = type; + return previousType; +} + +// types +void GenTemplateInstance::visit(PointerToMemberType * /*ty*/) +{ + Q_ASSERT(false); +} + +void GenTemplateInstance::visit(PointerType *ty) +{ + FullySpecifiedType elementType = subst(ty->elementType()); + _type.setType(_control->pointerType(elementType)); +} + +void GenTemplateInstance::visit(ReferenceType *ty) +{ + FullySpecifiedType elementType = subst(ty->elementType()); + _type.setType(_control->referenceType(elementType)); +} + +void GenTemplateInstance::visit(ArrayType *ty) +{ + FullySpecifiedType elementType = subst(ty->elementType()); + _type.setType(_control->arrayType(elementType, ty->size())); +} + +void GenTemplateInstance::visit(NamedType *ty) +{ + Name *name = ty->name(); + _type.setType(subst(name).type()); +} + +void GenTemplateInstance::visit(Function *ty) +{ + Name *name = ty->name(); + FullySpecifiedType returnType = subst(ty->returnType()); + + Function *fun = _control->newFunction(0, name); + fun->setScope(ty->scope()); + fun->setConst(ty->isConst()); + fun->setVolatile(ty->isVolatile()); + fun->setReturnType(returnType); + for (unsigned i = 0; i < ty->argumentCount(); ++i) { + Symbol *arg = ty->argumentAt(i); + FullySpecifiedType argTy = subst(arg->type()); + Argument *newArg = _control->newArgument(0, arg->name()); + newArg->setType(argTy); + fun->arguments()->enterSymbol(newArg); + } + _type.setType(fun); +} + +void GenTemplateInstance::visit(VoidType *) +{ /* nothing to do*/ } + +void GenTemplateInstance::visit(IntegerType *) +{ /* nothing to do*/ } + +void GenTemplateInstance::visit(FloatType *) +{ /* nothing to do*/ } + +void GenTemplateInstance::visit(Namespace *) +{ Q_ASSERT(false); } + +void GenTemplateInstance::visit(Class *) +{ Q_ASSERT(false); } + +void GenTemplateInstance::visit(Enum *) +{ Q_ASSERT(false); } + +// names +void GenTemplateInstance::visit(NameId *) +{ Q_ASSERT(false); } + +void GenTemplateInstance::visit(TemplateNameId *) +{ Q_ASSERT(false); } + +void GenTemplateInstance::visit(DestructorNameId *) +{ Q_ASSERT(false); } + +void GenTemplateInstance::visit(OperatorNameId *) +{ Q_ASSERT(false); } + +void GenTemplateInstance::visit(ConversionNameId *) +{ Q_ASSERT(false); } + +void GenTemplateInstance::visit(QualifiedNameId *) +{ Q_ASSERT(false); } + diff --git a/src/libs/cplusplus/GenTemplateInstance.h b/src/libs/cplusplus/GenTemplateInstance.h new file mode 100644 index 0000000000..a4845f8bc3 --- /dev/null +++ b/src/libs/cplusplus/GenTemplateInstance.h @@ -0,0 +1,58 @@ +#ifndef GENTEMPLATEINSTANCE_H +#define GENTEMPLATEINSTANCE_H + +#include <TypeVisitor.h> +#include <NameVisitor.h> +#include <FullySpecifiedType.h> + +#include <QtCore/QList> +#include <QtCore/QPair> + +namespace CPlusPlus { + +class CPLUSPLUS_EXPORT GenTemplateInstance: protected TypeVisitor, protected NameVisitor +{ +public: + typedef QList< QPair<Name *, FullySpecifiedType> > Substitution; + +public: + GenTemplateInstance(Control *control, const Substitution &substitution); + + FullySpecifiedType operator()(const FullySpecifiedType &ty); + +protected: + FullySpecifiedType subst(Name *name); + FullySpecifiedType subst(const FullySpecifiedType &ty); + + FullySpecifiedType switchType(const FullySpecifiedType &type); + + virtual void visit(PointerToMemberType * /*ty*/); + virtual void visit(PointerType *ty); + virtual void visit(ReferenceType *ty); + virtual void visit(ArrayType *ty); + virtual void visit(NamedType *ty); + virtual void visit(Function *ty); + virtual void visit(VoidType *); + virtual void visit(IntegerType *); + virtual void visit(FloatType *); + virtual void visit(Namespace *); + virtual void visit(Class *); + virtual void visit(Enum *); + + // names + virtual void visit(NameId *); + virtual void visit(TemplateNameId *); + virtual void visit(DestructorNameId *); + virtual void visit(OperatorNameId *); + virtual void visit(ConversionNameId *); + virtual void visit(QualifiedNameId *); + +private: + Control *_control; + FullySpecifiedType _type; + const Substitution _substitution; +}; + +} // end of namespace CPlusPlus + +#endif // GENTEMPLATEINSTANCE_H diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index 7c9eedebd5..f89c2c9afd 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -30,6 +30,7 @@ #include "ResolveExpression.h" #include "LookupContext.h" #include "Overview.h" +#include "GenTemplateInstance.h" #include <Control.h> #include <AST.h> @@ -49,151 +50,6 @@ using namespace CPlusPlus; namespace { -typedef QList< QPair<Name *, FullySpecifiedType> > Substitution; - -class GenerateInstance: protected TypeVisitor, protected NameVisitor -{ - Control *_control; - FullySpecifiedType _type; - const Substitution _substitution; - -public: - GenerateInstance(Control *control, const Substitution &substitution) - : _control(control), - _substitution(substitution) - { } - - FullySpecifiedType operator()(const FullySpecifiedType &ty) - { return subst(ty); } - -protected: - FullySpecifiedType subst(Name *name) - { - if (TemplateNameId *t = name->asTemplateNameId()) { - QVarLengthArray<FullySpecifiedType, 8> args(t->templateArgumentCount()); - - for (unsigned i = 0; i < t->templateArgumentCount(); ++i) - args[i] = subst(t->templateArgumentAt(i)); - - TemplateNameId *n = _control->templateNameId(t->identifier(), - args.data(), args.size()); - - return FullySpecifiedType(_control->namedType(n)); - } else if (name->isQualifiedNameId()) { - // ### implement me - } - - for (int i = 0; i < _substitution.size(); ++i) { - const QPair<Name *, FullySpecifiedType> s = _substitution.at(i); - if (name->isEqualTo(s.first)) - return s.second; - } - - return FullySpecifiedType(_control->namedType(name)); - } - - FullySpecifiedType subst(const FullySpecifiedType &ty) - { - FullySpecifiedType previousType = switchType(ty); - TypeVisitor::accept(ty.type()); - return switchType(previousType); - } - - FullySpecifiedType switchType(const FullySpecifiedType &type) - { - FullySpecifiedType previousType = _type; - _type = type; - return previousType; - } - - // types - virtual void visit(PointerToMemberType * /*ty*/) - { - Q_ASSERT(false); - } - - virtual void visit(PointerType *ty) - { - FullySpecifiedType elementType = subst(ty->elementType()); - _type.setType(_control->pointerType(elementType)); - } - - virtual void visit(ReferenceType *ty) - { - FullySpecifiedType elementType = subst(ty->elementType()); - _type.setType(_control->referenceType(elementType)); - } - - virtual void visit(ArrayType *ty) - { - FullySpecifiedType elementType = subst(ty->elementType()); - _type.setType(_control->arrayType(elementType, ty->size())); - } - - virtual void visit(NamedType *ty) - { - Name *name = ty->name(); - _type.setType(subst(name).type()); - } - - virtual void visit(Function *ty) - { - Name *name = ty->name(); - FullySpecifiedType returnType = subst(ty->returnType()); - - Function *fun = _control->newFunction(0, name); - fun->setScope(ty->scope()); - fun->setConst(ty->isConst()); - fun->setVolatile(ty->isVolatile()); - fun->setReturnType(returnType); - for (unsigned i = 0; i < ty->argumentCount(); ++i) { - Symbol *arg = ty->argumentAt(i); - FullySpecifiedType argTy = subst(arg->type()); - Argument *newArg = _control->newArgument(0, arg->name()); - newArg->setType(argTy); - fun->arguments()->enterSymbol(newArg); - } - _type.setType(fun); - } - - virtual void visit(VoidType *) - { /* nothing to do*/ } - - virtual void visit(IntegerType *) - { /* nothing to do*/ } - - virtual void visit(FloatType *) - { /* nothing to do*/ } - - virtual void visit(Namespace *) - { Q_ASSERT(false); } - - virtual void visit(Class *) - { Q_ASSERT(false); } - - virtual void visit(Enum *) - { Q_ASSERT(false); } - - // names - virtual void visit(NameId *) - { Q_ASSERT(false); } - - virtual void visit(TemplateNameId *) - { Q_ASSERT(false); } - - virtual void visit(DestructorNameId *) - { Q_ASSERT(false); } - - virtual void visit(OperatorNameId *) - { Q_ASSERT(false); } - - virtual void visit(ConversionNameId *) - { Q_ASSERT(false); } - - virtual void visit(QualifiedNameId *) - { Q_ASSERT(false); } -}; - template <typename _Tp> static QList<_Tp> removeDuplicates(const QList<_Tp> &results) { @@ -286,9 +142,14 @@ bool ResolveExpression::visit(ConditionAST *) return false; } -bool ResolveExpression::visit(ConditionalExpressionAST *) +bool ResolveExpression::visit(ConditionalExpressionAST *ast) { - // nothing to do. + if (ast->left_expression) + accept(ast->left_expression); + + else if (ast->right_expression) + accept(ast->right_expression); + return false; } @@ -300,7 +161,8 @@ bool ResolveExpression::visit(CppCastExpressionAST *ast) bool ResolveExpression::visit(DeleteExpressionAST *) { - // nothing to do. + FullySpecifiedType ty(control()->voidType()); + addResult(ty); return false; } @@ -310,8 +172,15 @@ bool ResolveExpression::visit(ArrayInitializerAST *) return false; } -bool ResolveExpression::visit(NewExpressionAST *) +bool ResolveExpression::visit(NewExpressionAST *ast) { + if (ast->new_type_id) { + Scope *scope = _context.expressionDocument()->globalSymbols(); + FullySpecifiedType ty = sem.check(ast->new_type_id->type_specifier, scope); + ty = sem.check(ast->new_type_id->ptr_operators, ty, scope); + FullySpecifiedType ptrTy(control()->pointerType(ty)); + addResult(ptrTy); + } // nothing to do. return false; } @@ -836,7 +705,7 @@ ResolveExpression::resolveMember(Name *memberName, Class *klass, unqualifiedNameId = q->unqualifiedNameId(); if (TemplateNameId *templId = unqualifiedNameId->asTemplateNameId()) { - Substitution subst; + GenTemplateInstance::Substitution subst; for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) { FullySpecifiedType templArgTy = templId->templateArgumentAt(i); @@ -846,7 +715,7 @@ ResolveExpression::resolveMember(Name *memberName, Class *klass, templArgTy)); } - GenerateInstance inst(control(), subst); + GenTemplateInstance inst(control(), subst); ty = inst(ty); } diff --git a/src/libs/cplusplus/cplusplus-lib.pri b/src/libs/cplusplus/cplusplus-lib.pri index 34caa520a8..812dbe0c9a 100644 --- a/src/libs/cplusplus/cplusplus-lib.pri +++ b/src/libs/cplusplus/cplusplus-lib.pri @@ -32,6 +32,7 @@ HEADERS += \ $$PWD/LookupContext.h \ $$PWD/CppBindings.h \ $$PWD/ASTParent.h \ + $$PWD/GenTemplateInstance.h \ $$PWD/CheckUndefinedSymbols.h \ $$PWD/PreprocessorClient.h \ $$PWD/PreprocessorEnvironment.h \ @@ -54,6 +55,7 @@ SOURCES += \ $$PWD/LookupContext.cpp \ $$PWD/CppBindings.cpp \ $$PWD/ASTParent.cpp \ + $$PWD/GenTemplateInstance.cpp \ $$PWD/CheckUndefinedSymbols.cpp \ $$PWD/PreprocessorClient.cpp \ $$PWD/PreprocessorEnvironment.cpp \ diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index 5ce662b998..c2bb068bce 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -545,6 +545,9 @@ Preprocessor::Preprocessor(Client *client, Environment *env) : client(client), env(env), _expand(env), + _skipping(MAX_LEVEL), + _trueTest(MAX_LEVEL), + _dot(_tokens.end()), _result(0), _markGeneratedTokens(false), _expandMacros(true) @@ -1268,7 +1271,7 @@ void Preprocessor::processIf(TokenIterator firstToken, TokenIterator lastToken) tokens.constEnd() - 1, condition); - _true_test[iflevel] = ! result.is_zero (); + _trueTest[iflevel] = ! result.is_zero (); _skipping[iflevel] = result.is_zero (); } } @@ -1282,7 +1285,7 @@ void Preprocessor::processElse(TokenIterator firstToken, TokenIterator lastToken } else if (iflevel > 0 && _skipping[iflevel - 1]) { _skipping[iflevel] = true; } else { - _skipping[iflevel] = _true_test[iflevel]; + _skipping[iflevel] = _trueTest[iflevel]; } } @@ -1296,7 +1299,7 @@ void Preprocessor::processElif(TokenIterator firstToken, TokenIterator lastToken // std::cerr << "*** WARNING: " << __FILE__ << __LINE__ << std::endl; } else if (iflevel == 0 && !skipping()) { // std::cerr << "*** WARNING #else without #if" << std::endl; - } else if (!_true_test[iflevel] && !_skipping[iflevel - 1]) { + } else if (!_trueTest[iflevel] && !_skipping[iflevel - 1]) { const char *first = startOfToken(*tk); const char *last = startOfToken(*lastToken); @@ -1312,7 +1315,7 @@ void Preprocessor::processElif(TokenIterator firstToken, TokenIterator lastToken tokens.constEnd() - 1, condition); - _true_test[iflevel] = ! result.is_zero (); + _trueTest[iflevel] = ! result.is_zero (); _skipping[iflevel] = result.is_zero (); } else { _skipping[iflevel] = true; @@ -1325,7 +1328,7 @@ void Preprocessor::processEndif(TokenIterator, TokenIterator) // std::cerr << "*** WARNING #endif without #if" << std::endl; } else { _skipping[iflevel] = false; - _true_test[iflevel] = false; + _trueTest[iflevel] = false; --iflevel; } @@ -1347,7 +1350,7 @@ void Preprocessor::processIfdef(bool checkUndefined, if (checkUndefined) value = ! value; - _true_test[iflevel] = value; + _trueTest[iflevel] = value; _skipping [iflevel] = ! value; } } @@ -1373,7 +1376,7 @@ void Preprocessor::resetIfLevel () { iflevel = 0; _skipping[iflevel] = false; - _true_test[iflevel] = false; + _trueTest[iflevel] = false; } Preprocessor::PP_DIRECTIVE_TYPE Preprocessor::classifyDirective(const QByteArray &directive) const @@ -1431,7 +1434,7 @@ bool Preprocessor::testIfLevel() { const bool result = !_skipping[iflevel++]; _skipping[iflevel] = _skipping[iflevel - 1]; - _true_test[iflevel] = false; + _trueTest[iflevel] = false; return result; } diff --git a/src/libs/cplusplus/pp-engine.h b/src/libs/cplusplus/pp-engine.h index 5203f7db0e..596a223e05 100644 --- a/src/libs/cplusplus/pp-engine.h +++ b/src/libs/cplusplus/pp-engine.h @@ -54,6 +54,7 @@ #include <Token.h> #include <QVector> +#include <QBitArray> namespace CPlusPlus { @@ -177,8 +178,8 @@ private: Environment *env; MacroExpander _expand; - bool _skipping[MAX_LEVEL]; // ### move in state - bool _true_test[MAX_LEVEL]; // ### move in state + QBitArray _skipping; // ### move in state + QBitArray _trueTest; // ### move in state int iflevel; // ### move in state QList<State> _savedStates; diff --git a/src/libs/cplusplus/pp-scanner.h b/src/libs/cplusplus/pp-scanner.h index 16baa57c37..a7e0051460 100644 --- a/src/libs/cplusplus/pp-scanner.h +++ b/src/libs/cplusplus/pp-scanner.h @@ -54,6 +54,8 @@ namespace CPlusPlus { struct pp_skip_blanks { int lines; + + pp_skip_blanks(): lines(0) {} const char *operator () (const char *first, const char *last); }; @@ -61,6 +63,7 @@ struct pp_skip_whitespaces { int lines; + pp_skip_whitespaces(): lines(0) {} const char *operator () (const char *first, const char *last); }; @@ -68,6 +71,7 @@ struct pp_skip_comment_or_divop { int lines; + pp_skip_comment_or_divop(): lines(0) {} const char *operator () (const char *first, const char *last); }; @@ -75,6 +79,7 @@ struct pp_skip_identifier { int lines; + pp_skip_identifier(): lines(0) {} const char *operator () (const char *first, const char *last); }; @@ -82,6 +87,7 @@ struct pp_skip_number { int lines; + pp_skip_number(): lines(0) {} const char *operator () (const char *first, const char *last); }; @@ -89,6 +95,7 @@ struct pp_skip_string_literal { int lines; + pp_skip_string_literal(): lines(0) {} const char *operator () (const char *first, const char *last); }; @@ -96,6 +103,7 @@ struct pp_skip_char_literal { int lines; + pp_skip_char_literal(): lines(0) {} const char *operator () (const char *first, const char *last); }; @@ -108,6 +116,7 @@ struct pp_skip_argument pp_skip_comment_or_divop skip_comment_or_divop; int lines; + pp_skip_argument(): lines(0) {} const char *operator () (const char *first, const char *last); }; |