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
Marco Bubke
flatpak-qt-creator
Commits
bb263645
Commit
bb263645
authored
Sep 30, 2009
by
Roberto Raggi
Browse files
Improved the resolving of member expressions.
parent
cae8a31a
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/libs/cplusplus/ResolveExpression.cpp
View file @
bb263645
...
...
@@ -623,141 +623,175 @@ bool ResolveExpression::visit(MemberAccessAST *ast)
memberName
=
ast
->
member_name
->
name
;
// Remember the access operator.
const
unsigned
accessOp
=
tokenKind
(
ast
->
access_token
);
const
int
accessOp
=
tokenKind
(
ast
->
access_token
);
_results
=
resolveMemberExpression
(
baseResults
,
accessOp
,
memberName
);
return
false
;
}
QList
<
ResolveExpression
::
Result
>
ResolveExpression
::
resolveMemberExpression
(
const
QList
<
Result
>
&
baseResults
,
unsigned
accessOp
,
Name
*
memberName
)
const
QList
<
Symbol
*>
ResolveExpression
::
resolveBaseExpression
(
const
QList
<
Result
>
&
baseResults
,
int
accessOp
)
const
{
ResolveClass
resolveClass
;
QList
<
Result
>
results
;
QList
<
Symbol
*>
classObjectCandidates
;
if
(
accessOp
==
T_ARROW
)
{
foreach
(
Result
p
,
baseResults
)
{
FullySpecifiedType
ty
=
p
.
first
;
if
(
baseResults
.
isEmpty
())
return
classObjectCandidates
;
if
(
ReferenceType
*
refTy
=
ty
->
asReferenceType
())
ty
=
refTy
->
elementType
();
Result
result
=
baseResults
.
first
();
if
(
NamedType
*
namedTy
=
ty
->
asNamedType
())
{
resolveClass
.
setPointerAccess
(
true
);
QList
<
Symbol
*>
classObjectCandidates
=
resolveClass
(
namedTy
,
p
,
_context
);
if
(
accessOp
==
T_ARROW
)
{
FullySpecifiedType
ty
=
result
.
first
.
simplified
();
foreach
(
Symbol
*
classObject
,
classObjectCandidates
)
{
results
+=
resolveMember
(
p
,
memberName
,
control
()
->
namedType
(
classObject
->
name
()),
// ### remove the call to namedType
classObject
->
asClass
());
if
(
Class
*
classTy
=
ty
->
asClassType
())
{
Symbol
*
symbol
=
result
.
second
;
if
(
symbol
&&
!
symbol
->
isClass
())
classObjectCandidates
.
append
(
classTy
);
}
else
if
(
NamedType
*
namedTy
=
ty
->
asNamedType
())
{
// ### This code is pretty slow.
const
QList
<
Symbol
*>
candidates
=
_context
.
resolve
(
namedTy
->
name
());
foreach
(
Symbol
*
candidate
,
candidates
)
{
if
(
candidate
->
isTypedef
())
{
ty
=
candidate
->
type
();
const
ResolveExpression
::
Result
r
(
ty
,
candidate
);
result
=
r
;
break
;
}
}
}
if
(
NamedType
*
namedTy
=
ty
->
asNamedType
())
{
ResolveClass
resolveClass
;
if
(
classObjectCandidates
.
isEmpty
())
{
resolveClass
.
setPointerAccess
(
false
);
classObjectCandidates
=
resolveClass
(
namedTy
,
p
,
_context
);
const
QList
<
Symbol
*>
candidates
=
resolveClass
(
result
,
_context
);
foreach
(
Symbol
*
classObject
,
candidates
)
{
const
QList
<
Result
>
overloads
=
resolveArrowOperator
(
result
,
namedTy
,
classObject
->
asClass
());
foreach
(
Symbol
*
classObject
,
classObjectCandidates
)
{
const
QList
<
Result
>
overloads
=
resolveArrowOperator
(
p
,
namedTy
,
classObject
->
asClass
());
foreach
(
Result
r
,
overloads
)
{
FullySpecifiedType
ty
=
r
.
first
;
Function
*
funTy
=
ty
->
asFunctionType
();
if
(
!
funTy
)
continue
;
foreach
(
Result
r
,
overloads
)
{
FullySpecifiedType
ty
=
r
.
first
;
Function
*
funTy
=
ty
->
asFunctionType
();
if
(
!
funTy
)
continue
;
ty
=
funTy
->
returnType
();
ty
=
funTy
->
returnType
()
.
simplified
()
;
if
(
ReferenceType
*
refTy
=
ty
->
asReferenceType
())
ty
=
refTy
->
elementType
();
if
(
PointerType
*
ptrTy
=
ty
->
asPointerType
())
{
if
(
NamedType
*
namedTy
=
ptrTy
->
elementType
()
->
asNamedType
())
{
const
QList
<
Symbol
*>
classes
=
resolveClass
(
namedTy
,
result
,
_context
);
if
(
PointerType
*
ptrTy
=
ty
->
asPointerType
()
)
{
if
(
NamedType
*
namedTy
=
ptrTy
->
elementType
()
->
asNamedType
(
))
results
+=
resolveMember
(
r
,
memberName
,
namedTy
);
foreach
(
Symbol
*
c
,
classes
)
{
if
(
!
classObjectCandidates
.
contains
(
c
))
classObjectCandidates
.
append
(
c
);
}
}
}
}
}
else
if
(
PointerType
*
ptrTy
=
ty
->
asPointerType
())
{
if
(
NamedType
*
namedTy
=
ptrTy
->
elementType
()
->
asNamedType
())
results
+=
resolveMember
(
p
,
memberName
,
namedTy
);
}
}
}
else
if
(
accessOp
==
T_DOT
)
{
// The base expression shall be a "class object" of a complete type.
foreach
(
Result
p
,
baseResults
)
{
FullySpecifiedType
ty
=
p
.
first
;
}
else
if
(
PointerType
*
ptrTy
=
ty
->
asPointerType
())
{
if
(
NamedType
*
namedTy
=
ptrTy
->
elementType
()
->
asNamedType
())
{
ResolveClass
resolveClass
;
if
(
ReferenceType
*
refTy
=
ty
->
asReferenceType
())
ty
=
refTy
->
elementType
(
);
const
QList
<
Symbol
*>
classes
=
resolveClass
(
namedTy
,
result
,
_context
);
if
(
NamedType
*
namedTy
=
ty
->
asNamedType
())
results
+=
resolveMember
(
p
,
memberName
,
namedTy
);
else
if
(
Function
*
fun
=
ty
->
asFunctionType
())
{
if
(
fun
->
scope
()
&&
(
fun
->
scope
()
->
isBlockScope
()
||
fun
->
scope
()
->
isNamespaceScope
()))
{
ty
=
fun
->
returnType
();
if
(
ReferenceType
*
refTy
=
ty
->
asReferenceType
())
ty
=
refTy
->
elementType
();
if
(
NamedType
*
namedTy
=
ty
->
asNamedType
())
results
+=
resolveMember
(
p
,
memberName
,
namedTy
);
foreach
(
Symbol
*
c
,
classes
)
{
if
(
!
classObjectCandidates
.
contains
(
c
))
classObjectCandidates
.
append
(
c
);
}
}
else
if
(
Class
*
classTy
=
ptrTy
->
elementType
()
->
asClassType
())
{
// typedef struct { int x } *Ptr;
// Ptr p;
// p->
classObjectCandidates
.
append
(
classTy
);
}
}
}
else
if
(
accessOp
==
T_DOT
)
{
FullySpecifiedType
ty
=
result
.
first
.
simplified
();
NamedType
*
namedTy
=
0
;
if
(
Class
*
classTy
=
ty
->
asClassType
())
{
Symbol
*
symbol
=
result
.
second
;
if
(
symbol
&&
!
symbol
->
isClass
())
classObjectCandidates
.
append
(
classTy
);
}
else
{
namedTy
=
ty
->
asNamedType
();
if
(
!
namedTy
)
{
Function
*
fun
=
ty
->
asFunctionType
();
if
(
fun
&&
fun
->
scope
()
&&
(
fun
->
scope
()
->
isBlockScope
()
||
fun
->
scope
()
->
isNamespaceScope
()))
namedTy
=
fun
->
returnType
()
->
asNamedType
();
}
}
if
(
namedTy
)
{
ResolveClass
resolveClass
;
const
QList
<
Symbol
*>
symbols
=
resolveClass
(
namedTy
,
result
,
_context
);
foreach
(
Symbol
*
symbol
,
symbols
)
{
if
(
classObjectCandidates
.
contains
(
symbol
))
continue
;
if
(
Class
*
klass
=
symbol
->
asClass
())
classObjectCandidates
.
append
(
klass
);
}
}
}
return
result
s
;
return
classObjectCandidate
s
;
}
QList
<
ResolveExpression
::
Result
>
ResolveExpression
::
resolveMember
(
const
Result
&
p
,
Name
*
memberName
,
NamedType
*
namedTy
)
const
ResolveExpression
::
resolveMember
Expression
(
const
QList
<
Result
>
&
baseResults
,
unsigned
accessOp
,
Name
*
memberName
)
const
{
ResolveClass
resolveClas
s
;
QList
<
Result
>
result
s
;
const
QList
<
Symbol
*>
classObjectCandidates
=
resolveClass
(
namedTy
,
p
,
_context
);
const
QList
<
Symbol
*>
classObjectCandidates
=
resolveBaseExpression
(
baseResults
,
accessOp
);
foreach
(
Symbol
*
candidate
,
classObjectCandidates
)
{
Class
*
klass
=
candidate
->
asClass
();
if
(
!
klass
)
continue
;
QList
<
Result
>
results
;
foreach
(
Symbol
*
classObject
,
classObjectCandidates
)
{
results
+=
resolveMember
(
p
,
memberName
,
namedTy
,
classObject
->
asClass
());
results
+=
resolveMember
(
memberName
,
klass
);
}
return
results
;
}
QList
<
ResolveExpression
::
Result
>
ResolveExpression
::
resolveMember
(
const
Result
&
,
Name
*
memberName
,
NamedType
*
namedTy
,
Class
*
klass
)
const
ResolveExpression
::
resolveMember
(
Name
*
memberName
,
Class
*
klass
)
const
{
QList
<
Result
>
results
;
QList
<
Scope
*>
scopes
;
_context
.
expand
(
klass
->
members
(),
_context
.
visibleScopes
(),
&
scopes
);
QList
<
Result
>
results
;
QList
<
Symbol
*>
candidates
=
_context
.
resolve
(
memberName
,
scopes
);
foreach
(
Symbol
*
candidate
,
candidates
)
{
FullySpecifiedType
ty
=
candidate
->
type
();
Name
*
unqualifiedNameId
=
namedTy
->
name
();
if
(
QualifiedNameId
*
q
=
namedTy
->
name
()
->
asQualifiedNameId
())
unqualifiedNameId
=
q
->
unqualifiedNameId
();
if
(
TemplateNameId
*
templId
=
unqualifiedNameId
->
asTemplateNameId
())
{
Substitution
subst
;
for
(
unsigned
i
=
0
;
i
<
templId
->
templateArgumentCount
();
++
i
)
{
FullySpecifiedType
templArgTy
=
templId
->
templateArgumentAt
(
i
);
if
(
i
<
klass
->
templateParameterCount
())
{
subst
.
append
(
qMakePair
(
klass
->
templateParameterAt
(
i
)
->
name
(),
templArgTy
));
if
(
Name
*
className
=
klass
->
name
())
{
Name
*
unqualifiedNameId
=
className
;
if
(
QualifiedNameId
*
q
=
className
->
asQualifiedNameId
())
unqualifiedNameId
=
q
->
unqualifiedNameId
();
if
(
TemplateNameId
*
templId
=
unqualifiedNameId
->
asTemplateNameId
())
{
Substitution
subst
;
for
(
unsigned
i
=
0
;
i
<
templId
->
templateArgumentCount
();
++
i
)
{
FullySpecifiedType
templArgTy
=
templId
->
templateArgumentAt
(
i
);
if
(
i
<
klass
->
templateParameterCount
())
subst
.
append
(
qMakePair
(
klass
->
templateParameterAt
(
i
)
->
name
(),
templArgTy
));
}
Instantiation
inst
(
control
(),
subst
);
ty
=
inst
(
ty
);
}
Instantiation
inst
(
control
(),
subst
);
ty
=
inst
(
ty
);
}
const
Result
result
(
ty
,
candidate
);
...
...
src/libs/cplusplus/ResolveExpression.h
View file @
bb263645
...
...
@@ -53,14 +53,7 @@ public:
unsigned
accessOp
,
Name
*
memberName
)
const
;
QList
<
Result
>
resolveMember
(
const
Result
&
result
,
Name
*
memberName
,
NamedType
*
namedTy
)
const
;
QList
<
Result
>
resolveMember
(
const
Result
&
result
,
Name
*
memberName
,
NamedType
*
namedTy
,
Class
*
klass
)
const
;
QList
<
Result
>
resolveMember
(
Name
*
memberName
,
Class
*
klass
)
const
;
QList
<
Result
>
resolveArrowOperator
(
const
Result
&
result
,
NamedType
*
namedTy
,
...
...
@@ -70,6 +63,10 @@ public:
NamedType
*
namedTy
,
Class
*
klass
)
const
;
QList
<
Symbol
*>
resolveBaseExpression
(
const
QList
<
Result
>
&
baseResults
,
int
accessOp
)
const
;
protected:
QList
<
Result
>
switchResults
(
const
QList
<
Result
>
&
symbols
);
...
...
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