summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r--src/libs/cplusplus/ExpressionUnderCursor.cpp1
-rw-r--r--src/libs/cplusplus/ExpressionUnderCursor.h1
-rw-r--r--src/libs/cplusplus/GenTemplateInstance.cpp145
-rw-r--r--src/libs/cplusplus/GenTemplateInstance.h58
-rw-r--r--src/libs/cplusplus/ResolveExpression.cpp171
-rw-r--r--src/libs/cplusplus/cplusplus-lib.pri2
-rw-r--r--src/libs/cplusplus/pp-engine.cpp19
-rw-r--r--src/libs/cplusplus/pp-engine.h5
-rw-r--r--src/libs/cplusplus/pp-scanner.h9
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);
};