[cfe-dev] WIP patch for qualified-ids in class member access
Douglas Gregor
dgregor at apple.com
Mon Jul 27 15:33:56 PDT 2009
On Jul 26, 2009, at 12:17 PM, James Porter wrote:
> James Porter wrote:
>> I've updated my patch (attached). The main change is that this
>> version
>> supports qualified-ids with overloaded operator->. Other than that,
>> most
>> of the changes are merely organizational.
>
> Ping! If anyone has a chance to look over this to evaluate the changes
> to this patch, that'd be excellent. I think I ended up posting it
> right
> around when all the C++ folks were busy in Germany at the Frankfurt
> meeting.
Your timing was perfect; I didn't even realize you'd posted a updated
patch :)
Some comments:
First of all, this patch breaks some tests that are currently working:
test/SemaCXX/class.cpp
test/SemaCXX/member-expr.cpp
test/SemaTemplate/ext-vector-type.cpp
test/SemaTemplate/instantiate-clang.cpp
test/SemaTemplate/instantiate-expr-4.cpp
We'll need all tests running cleanly before we can commit this change.
+Action::OwningExprResult
+Sema::ActOnCXXEnterMemberScope(Scope *S, CXXScopeSpec &SS, ExprArg
Base,
+ tok::TokenKind OpKind) {
+ Expr *BaseExpr = Base.takeAs<Expr>();
+ assert(BaseExpr && "no record expansion");
At this point, nobody "owns" the expression BaseExpr. So, if we return
without explicitly destroying it, we'll leak the expression. I'd
suggest letting Base own the expression. Then, code like this:
+ if (BaseType->isDependentType())
+ return Owned(BaseExpr);
can just move Base out to the result, e.g.,
if (BaseType->isDependentType())
return move(Base);
Then, when coping with an overloaded operator->:
+ Base = BuildOverloadedArrowExpr(S, BaseExpr, BaseExpr-
>getExprLoc());
+ BaseExpr = Base.takeAs<Expr>();
+ if (BaseExpr == NULL)
+ return ExprError();
Replace the "takeAs" with "getAs", so we don't take ownership from
Base. If Base always owns the expression, it'll always clean it up
properly.
+ if (!BaseType->isRecordType()) {
+ return ExprError(Diag(BaseExpr->getExprLoc(),
+
diag::err_typecheck_member_reference_struct_union)
+ << BaseType << BaseExpr->getSourceRange());
+ }
We can also end up with various Objective-C types and ExtVectorTypes
here, so this diagnostic comes too early. (That's why SemaTemplate/ext-
vector-type.cpp is failing).
+ // FIXME: we should probably do something with the LookupResult
+ if (SS && SS->isSet()) {
+ NestedNameSpecifier *Prefix
+ = static_cast<NestedNameSpecifier *>(SS->getScopeRep());
+ assert(Prefix && Prefix->getKind() ==
NestedNameSpecifier::TypeSpec
+ && "Nested name specifier does not name a type");
+
+ Type *T = Prefix->getAsType();
+ assert(T && "couldn't get type");
+ DeclarationName Name = T->getAsRecordType()->getDecl()-
>getDeclName();
+ LookupResult Result = LookupQualifiedName(RDecl, Name,
LookupMemberName,
+ false);
+ if (!Result.getAsDecl())
+ return ExprError(Diag(SS->getBeginLoc(),
+ diag::err_not_direct_base_or_virtual)
+ << Name.getAsIdentifierInfo() << BaseType);
+ }
+
// The record definition is complete, now make sure the member
is valid.
// FIXME: Qualified name lookup for C++ is a bit more
complicated than this.
LookupResult Result
I don't really understand what the lookup above is meant to do. I
expected that it would take the nested-name-specifier in SS and try to
find the member name (Member) within that scope-specifier, but instead
it's looking for the name in the nested-name-specifier itself (?)
I had expected that the lookup for the member would do something like
this:
// Perform name lookup for the member
DeclContext *DC = RDecl;
if (SS && SS->isSet()) {
// If the member name was a qualified-id, look into the
// nested-name-specifier.
DC = computeDeclContext(*SS, false);
assert(DC && "Cannot handle non-computable dependent contexts in
lookup");
}
LookupResult Result
= LookupQualifiedName(DC, DeclarationName(&Member),
LookupMemberName, false);
That would replace the current LookupQualifiedName call, which always
looks into RDecl.
- Doug
More information about the cfe-dev
mailing list