Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Tobias Hunger
qt-creator
Commits
63138eb8
Commit
63138eb8
authored
Dec 10, 2010
by
Roberto Raggi
Browse files
Added some initial support for function overloading.
parent
610023f8
Changes
10
Hide whitespace changes
Inline
Side-by-side
src/libs/cplusplus/CppDocument.cpp
View file @
63138eb8
...
...
@@ -42,6 +42,9 @@
#include
<AST.h>
#include
<Scope.h>
#include
<SymbolVisitor.h>
#include
<NameVisitor.h>
#include
<TypeVisitor.h>
#include
<CoreTypes.h>
#include
<QtCore/QByteArray>
#include
<QtCore/QBitArray>
...
...
@@ -789,9 +792,8 @@ Symbol *Snapshot::findMatchingDefinition(Symbol *declaration) const
Function
*
best
=
0
;
foreach
(
Function
*
fun
,
viableFunctions
)
{
if
(
fun
->
unqualifiedName
()
->
isEqualTo
(
declaration
->
unqualifiedName
()))
if
(
!
(
fun
->
unqualifiedName
()
&&
fun
->
unqualifiedName
()
->
isEqualTo
(
declaration
->
unqualifiedName
()))
)
continue
;
else
if
(
fun
->
argumentCount
()
==
declarationTy
->
argumentCount
())
{
if
(
!
best
)
best
=
fun
;
...
...
src/libs/cplusplus/ResolveExpression.cpp
View file @
63138eb8
...
...
@@ -75,7 +75,8 @@ ResolveExpression::ResolveExpression(const LookupContext &context)
:
ASTVisitor
(
context
.
expressionDocument
()
->
translationUnit
()),
_scope
(
0
),
_context
(
context
),
bind
(
context
.
expressionDocument
()
->
translationUnit
())
bind
(
context
.
expressionDocument
()
->
translationUnit
()),
_reference
(
false
)
{
}
ResolveExpression
::~
ResolveExpression
()
...
...
@@ -84,19 +85,26 @@ ResolveExpression::~ResolveExpression()
QList
<
LookupItem
>
ResolveExpression
::
operator
()(
ExpressionAST
*
ast
,
Scope
*
scope
)
{
return
resolve
(
ast
,
scope
);
}
QList
<
LookupItem
>
ResolveExpression
::
resolve
(
ExpressionAST
*
ast
,
Scope
*
scope
)
QList
<
LookupItem
>
ResolveExpression
::
reference
(
ExpressionAST
*
ast
,
Scope
*
scope
)
{
return
resolve
(
ast
,
scope
,
true
);
}
QList
<
LookupItem
>
ResolveExpression
::
resolve
(
ExpressionAST
*
ast
,
Scope
*
scope
,
bool
ref
)
{
if
(
!
scope
)
return
QList
<
LookupItem
>
();
Scope
*
previousVisibleSymbol
=
_scope
;
_scope
=
scope
;
const
QList
<
LookupItem
>
result
=
resolve
(
ast
);
_scope
=
previousVisibleSymbol
;
std
::
swap
(
_scope
,
scope
);
std
::
swap
(
_reference
,
ref
);
const
QList
<
LookupItem
>
result
=
expression
(
ast
);
std
::
swap
(
_reference
,
ref
);
std
::
swap
(
_scope
,
scope
);
return
result
;
}
QList
<
LookupItem
>
ResolveExpression
::
resolve
(
ExpressionAST
*
ast
)
QList
<
LookupItem
>
ResolveExpression
::
expression
(
ExpressionAST
*
ast
)
{
const
QList
<
LookupItem
>
previousResults
=
switchResults
(
QList
<
LookupItem
>
());
accept
(
ast
);
...
...
@@ -441,27 +449,18 @@ bool ResolveExpression::visit(ConversionFunctionIdAST *)
return
false
;
}
bool
ResolveExpression
::
maybeValidPrototype
(
Function
*
funTy
,
unsigned
actualArgumentCount
)
const
bool
ResolveExpression
::
maybeValidPrototype
(
Function
*
funTy
,
unsigned
actualArgumentCount
)
{
unsigned
minNumberArguments
=
0
;
for
(;
minNumberArguments
<
funTy
->
argumentCount
();
++
minNumberArguments
)
{
Argument
*
arg
=
funTy
->
argumentAt
(
minNumberArguments
)
->
asArgument
();
if
(
arg
->
hasInitializer
())
break
;
}
if
(
actualArgumentCount
<
minNumberArguments
)
{
// not enough arguments.
return
false
;
}
else
if
(
!
funTy
->
isVariadic
()
&&
actualArgumentCount
>
funTy
->
argumentCount
())
{
// too many arguments.
return
false
;
}
return
funTy
->
maybeValidPrototype
(
actualArgumentCount
);
}
return
true
;
bool
ResolveExpression
::
implicitConversion
(
const
FullySpecifiedType
&
sourceTy
,
const
FullySpecifiedType
&
targetTy
)
const
{
if
(
sourceTy
.
isEqualTo
(
targetTy
))
return
true
;
else
if
(
sourceTy
.
simplified
().
isEqualTo
(
targetTy
.
simplified
()))
return
true
;
return
false
;
}
bool
ResolveExpression
::
visit
(
CallAST
*
ast
)
...
...
@@ -469,14 +468,55 @@ bool ResolveExpression::visit(CallAST *ast)
const
QList
<
LookupItem
>
baseResults
=
resolve
(
ast
->
base_expression
,
_scope
);
// Compute the types of the actual arguments.
int
actualArgumentCount
=
0
;
unsigned
actualArgumentCount
=
0
;
//
QList< QList<
Result
> > arguments;
QList
<
QList
<
LookupItem
>
>
arguments
;
for
(
ExpressionListAST
*
exprIt
=
ast
->
expression_list
;
exprIt
;
exprIt
=
exprIt
->
next
)
{
//arguments.append(resolve(exprIt->expression));
if
(
_reference
)
arguments
.
append
(
resolve
(
exprIt
->
value
,
_scope
));
++
actualArgumentCount
;
}
if
(
_reference
)
{
_results
.
clear
();
foreach
(
const
LookupItem
&
base
,
baseResults
)
{
if
(
Function
*
funTy
=
base
.
type
()
->
asFunctionType
())
{
if
(
!
maybeValidPrototype
(
funTy
,
actualArgumentCount
))
continue
;
int
score
=
0
;
for
(
unsigned
i
=
0
;
i
<
funTy
->
argumentCount
();
++
i
)
{
const
FullySpecifiedType
formalTy
=
funTy
->
argumentAt
(
i
)
->
type
();
FullySpecifiedType
actualTy
;
if
(
i
<
unsigned
(
arguments
.
size
()))
{
const
QList
<
LookupItem
>
actual
=
arguments
.
at
(
i
);
if
(
actual
.
isEmpty
())
continue
;
actualTy
=
actual
.
first
().
type
();
}
else
actualTy
=
formalTy
;
if
(
implicitConversion
(
actualTy
,
formalTy
))
++
score
;
}
if
(
score
)
_results
.
prepend
(
base
);
else
_results
.
append
(
base
);
}
}
if
(
_results
.
isEmpty
())
_results
=
baseResults
;
return
false
;
}
const
Name
*
functionCallOp
=
control
()
->
operatorNameId
(
OperatorNameId
::
FunctionCallOp
);
foreach
(
const
LookupItem
&
result
,
baseResults
)
{
...
...
@@ -513,7 +553,7 @@ bool ResolveExpression::visit(CallAST *ast)
bool
ResolveExpression
::
visit
(
ArrayAccessAST
*
ast
)
{
const
QList
<
LookupItem
>
baseResults
=
resolve
(
ast
->
base_expression
,
_scope
);
const
QList
<
LookupItem
>
indexResults
=
resolve
(
ast
->
expression
);
const
QList
<
LookupItem
>
indexResults
=
resolve
(
ast
->
expression
,
_scope
);
const
Name
*
arrayAccessOp
=
control
()
->
operatorNameId
(
OperatorNameId
::
ArrayAccessOp
);
...
...
@@ -709,7 +749,7 @@ bool ResolveExpression::visit(PostIncrDecrAST *ast)
bool
ResolveExpression
::
visit
(
ObjCMessageExpressionAST
*
ast
)
{
const
QList
<
LookupItem
>
receiverResults
=
resolve
(
ast
->
receiver_expression
);
const
QList
<
LookupItem
>
receiverResults
=
resolve
(
ast
->
receiver_expression
,
_scope
);
foreach
(
const
LookupItem
&
result
,
receiverResults
)
{
FullySpecifiedType
ty
=
result
.
type
().
simplified
();
...
...
src/libs/cplusplus/ResolveExpression.h
View file @
63138eb8
...
...
@@ -45,7 +45,8 @@ public:
virtual
~
ResolveExpression
();
QList
<
LookupItem
>
operator
()(
ExpressionAST
*
ast
,
Scope
*
scope
);
QList
<
LookupItem
>
resolve
(
ExpressionAST
*
ast
,
Scope
*
scope
);
QList
<
LookupItem
>
resolve
(
ExpressionAST
*
ast
,
Scope
*
scope
,
bool
ref
=
false
);
QList
<
LookupItem
>
reference
(
ExpressionAST
*
ast
,
Scope
*
scope
);
ClassOrNamespace
*
baseExpression
(
const
QList
<
LookupItem
>
&
baseResults
,
int
accessOp
,
...
...
@@ -56,7 +57,7 @@ public:
protected:
ClassOrNamespace
*
findClass
(
const
FullySpecifiedType
&
ty
,
Scope
*
scope
)
const
;
QList
<
LookupItem
>
resolve
(
ExpressionAST
*
ast
);
QList
<
LookupItem
>
expression
(
ExpressionAST
*
ast
);
QList
<
LookupItem
>
switchResults
(
const
QList
<
LookupItem
>
&
symbols
);
FullySpecifiedType
instantiate
(
const
Name
*
className
,
Symbol
*
candidate
)
const
;
...
...
@@ -69,7 +70,8 @@ protected:
void
addResults
(
const
QList
<
Symbol
*>
&
symbols
);
void
addResults
(
const
QList
<
LookupItem
>
&
items
);
bool
maybeValidPrototype
(
Function
*
funTy
,
unsigned
actualArgumentCount
)
const
;
static
bool
maybeValidPrototype
(
Function
*
funTy
,
unsigned
actualArgumentCount
);
bool
implicitConversion
(
const
FullySpecifiedType
&
sourceTy
,
const
FullySpecifiedType
&
targetTy
)
const
;
using
ASTVisitor
::
visit
;
...
...
@@ -119,6 +121,7 @@ private:
LookupContext
_context
;
Bind
bind
;
QList
<
LookupItem
>
_results
;
bool
_reference
;
};
}
// end of namespace CPlusPlus
...
...
src/libs/cplusplus/TypeOfExpression.cpp
View file @
63138eb8
...
...
@@ -84,6 +84,20 @@ QList<LookupItem> TypeOfExpression::operator()(const QString &expression,
scope
);
}
QList
<
LookupItem
>
TypeOfExpression
::
reference
(
const
QString
&
expression
,
Scope
*
scope
,
PreprocessMode
mode
)
{
QString
code
=
expression
;
if
(
mode
==
Preprocess
)
code
=
preprocessedExpression
(
expression
);
Document
::
Ptr
expressionDoc
=
documentForExpression
(
code
);
expressionDoc
->
check
();
return
reference
(
extractExpressionAST
(
expressionDoc
),
expressionDoc
,
scope
);
}
QList
<
LookupItem
>
TypeOfExpression
::
operator
()(
ExpressionAST
*
expression
,
Document
::
Ptr
document
,
Scope
*
scope
)
...
...
@@ -104,6 +118,26 @@ QList<LookupItem> TypeOfExpression::operator()(ExpressionAST *expression,
return
items
;
}
QList
<
LookupItem
>
TypeOfExpression
::
reference
(
ExpressionAST
*
expression
,
Document
::
Ptr
document
,
Scope
*
scope
)
{
m_ast
=
expression
;
m_scope
=
scope
;
m_lookupContext
=
LookupContext
(
document
,
m_thisDocument
,
m_snapshot
);
m_lookupContext
.
setBindings
(
m_bindings
);
ResolveExpression
resolve
(
m_lookupContext
);
const
QList
<
LookupItem
>
items
=
resolve
.
reference
(
m_ast
,
scope
);
if
(
!
m_bindings
)
m_lookupContext
=
resolve
.
context
();
return
items
;
}
QString
TypeOfExpression
::
preprocess
(
const
QString
&
expression
)
const
{
return
preprocessedExpression
(
expression
);
...
...
@@ -179,3 +213,4 @@ QString TypeOfExpression::preprocessedExpression(const QString &expression) cons
const
QByteArray
preprocessedCode
=
preproc
(
"<expression>"
,
code
);
return
QString
::
fromUtf8
(
preprocessedCode
.
constData
(),
preprocessedCode
.
size
());
}
src/libs/cplusplus/TypeOfExpression.h
View file @
63138eb8
...
...
@@ -98,6 +98,14 @@ public:
Document
::
Ptr
document
,
Scope
*
scope
);
QList
<
LookupItem
>
reference
(
const
QString
&
expression
,
Scope
*
scope
,
PreprocessMode
mode
=
NoPreprocess
);
QList
<
LookupItem
>
reference
(
ExpressionAST
*
expression
,
Document
::
Ptr
document
,
Scope
*
scope
);
QString
preprocess
(
const
QString
&
expression
)
const
;
/**
...
...
src/plugins/cppeditor/cppeditor.cpp
View file @
63138eb8
...
...
@@ -76,6 +76,7 @@
#include
<extensionsystem/pluginmanager.h>
#include
<projectexplorer/projectexplorerconstants.h>
#include
<texteditor/basetextdocument.h>
#include
<texteditor/basetextdocumentlayout.h>
#include
<texteditor/fontsettings.h>
#include
<texteditor/tabsettings.h>
#include
<texteditor/texteditorconstants.h>
...
...
@@ -1265,6 +1266,13 @@ CPPEditor::Link CPPEditor::attemptFuncDeclDef(const QTextCursor &cursor, const D
return
result
;
}
for
(
int
i
=
path
.
size
()
-
1
;
i
!=
-
1
;
--
i
)
{
AST
*
node
=
path
.
at
(
i
);
if
(
node
->
asParameterDeclaration
()
!=
0
)
return
result
;
}
AST
*
declParent
=
0
;
DeclaratorAST
*
decl
=
0
;
for
(
int
i
=
path
.
size
()
-
2
;
i
>
0
;
--
i
)
{
...
...
@@ -1431,11 +1439,27 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
// Evaluate the type of the expression under the cursor
ExpressionUnderCursor
expressionUnderCursor
;
const
QString
expression
=
expressionUnderCursor
(
tc
);
QString
expression
=
expressionUnderCursor
(
tc
);
for
(
int
pos
=
tc
.
position
();;
++
pos
)
{
const
QChar
ch
=
characterAt
(
pos
);
if
(
ch
.
isSpace
())
continue
;
else
{
if
(
ch
==
QLatin1Char
(
'('
)
&&
!
expression
.
isEmpty
())
{
tc
.
setPosition
(
pos
);
if
(
TextEditor
::
TextBlockUserData
::
findNextClosingParenthesis
(
&
tc
,
true
))
{
expression
.
append
(
tc
.
selectedText
());
}
}
break
;
}
}
TypeOfExpression
typeOfExpression
;
typeOfExpression
.
init
(
doc
,
snapshot
);
const
QList
<
LookupItem
>
resolvedSymbols
=
typeOfExpression
(
expression
,
scope
,
TypeOfExpression
::
Preprocess
);
const
QList
<
LookupItem
>
resolvedSymbols
=
typeOfExpression
.
reference
(
expression
,
scope
,
TypeOfExpression
::
Preprocess
);
if
(
!
resolvedSymbols
.
isEmpty
())
{
LookupItem
result
=
skipForwardDeclarations
(
resolvedSymbols
);
...
...
@@ -1473,16 +1497,6 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
link
.
begin
=
beginOfToken
;
link
.
end
=
endOfToken
;
return
link
;
// This would jump to the type of a name
#if 0
} else if (NamedType *namedType = firstType->asNamedType()) {
QList<Symbol *> candidates = context.resolve(namedType->name());
if (!candidates.isEmpty()) {
Symbol *s = candidates.takeFirst();
openCppEditorAt(s->fileName(), s->line(), s->column());
}
#endif
}
}
else
{
// Handle macro uses
...
...
src/shared/cplusplus/Control.cpp
View file @
63138eb8
...
...
@@ -759,6 +759,22 @@ const Identifier *Control::objcCopyId() const
const
Identifier
*
Control
::
objcNonatomicId
()
const
{
return
d
->
objcNonatomicId
;
}
Symbol
**
Control
::
firstSymbol
()
const
{
if
(
d
->
symbols
.
empty
())
return
0
;
return
&*
d
->
symbols
.
begin
();
}
Symbol
**
Control
::
lastSymbol
()
const
{
if
(
d
->
symbols
.
empty
())
return
0
;
return
&*
d
->
symbols
.
begin
()
+
d
->
symbols
.
size
();
}
bool
Control
::
hasSymbol
(
Symbol
*
symbol
)
const
{
return
std
::
find
(
d
->
symbols
.
begin
(),
d
->
symbols
.
end
(),
symbol
)
!=
d
->
symbols
.
end
();
...
...
src/shared/cplusplus/Control.h
View file @
63138eb8
...
...
@@ -212,6 +212,9 @@ public:
const
NumericLiteral
*
numericLiteral
(
const
char
*
chars
,
unsigned
size
);
const
NumericLiteral
*
numericLiteral
(
const
char
*
chars
);
Symbol
**
firstSymbol
()
const
;
Symbol
**
lastSymbol
()
const
;
bool
hasSymbol
(
Symbol
*
symbol
)
const
;
void
squeeze
();
...
...
src/shared/cplusplus/Symbols.cpp
View file @
63138eb8
...
...
@@ -362,6 +362,30 @@ void Function::visitSymbol0(SymbolVisitor *visitor)
}
}
bool
Function
::
maybeValidPrototype
(
unsigned
actualArgumentCount
)
const
{
unsigned
minNumberArguments
=
0
;
for
(;
minNumberArguments
<
this
->
argumentCount
();
++
minNumberArguments
)
{
Argument
*
arg
=
this
->
argumentAt
(
minNumberArguments
)
->
asArgument
();
if
(
arg
->
hasInitializer
())
break
;
}
if
(
actualArgumentCount
<
minNumberArguments
)
{
// not enough arguments.
return
false
;
}
else
if
(
!
this
->
isVariadic
()
&&
actualArgumentCount
>
this
->
argumentCount
())
{
// too many arguments.
return
false
;
}
return
true
;
}
Block
::
Block
(
TranslationUnit
*
translationUnit
,
unsigned
sourceLocation
)
:
Scope
(
translationUnit
,
sourceLocation
,
/*name = */
0
)
{
}
...
...
src/shared/cplusplus/Symbols.h
View file @
63138eb8
...
...
@@ -350,6 +350,8 @@ public:
bool
isAmbiguous
()
const
;
// internal
void
setAmbiguous
(
bool
isAmbiguous
);
// internal
bool
maybeValidPrototype
(
unsigned
actualArgumentCount
)
const
;
protected:
virtual
void
visitSymbol0
(
SymbolVisitor
*
visitor
);
virtual
void
accept0
(
TypeVisitor
*
visitor
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment