[cfe-commits] r120055 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/AST/ExprClassification.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplate.cpp
John McCall
rjmccall at apple.com
Tue Nov 23 12:48:44 PST 2010
Author: rjmccall
Date: Tue Nov 23 14:48:44 2010
New Revision: 120055
URL: http://llvm.org/viewvc/llvm-project?rev=120055&view=rev
Log:
A few tweaks to the value-kind computation:
- Default argument expressions pick up the value kind of the incoming
expression, not the value kind of the parameter it initializes.
- When building a template argument for substitution, A::x is an rvalue
if x is an instance method.
- Anonymous struct/union paths pick up value kind the same way that
normal member accesses do; extract out a common code path for this.
Enable the value-kind assertion, now that it passes self-host.
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/lib/AST/ExprClassification.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=120055&r1=120054&r2=120055&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Nov 23 14:48:44 2010
@@ -577,12 +577,14 @@
param->hasUnparsedDefaultArg()
? param->getType().getNonReferenceType()
: param->getDefaultArg()->getType(),
- getValueKindForType(param->getType()), OK_Ordinary, false, false),
+ param->getDefaultArg()->getValueKind(),
+ param->getDefaultArg()->getObjectKind(), false, false),
Param(param, false), Loc(Loc) { }
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
Expr *SubExpr)
- : Expr(SC, SubExpr->getType(), SubExpr->getValueKind(), OK_Ordinary,
+ : Expr(SC, SubExpr->getType(),
+ SubExpr->getValueKind(), SubExpr->getObjectKind(),
false, false), Param(param, true), Loc(Loc) {
*reinterpret_cast<Expr **>(this + 1) = SubExpr;
}
Modified: cfe/trunk/lib/AST/ExprClassification.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=120055&r1=120054&r2=120055&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprClassification.cpp (original)
+++ cfe/trunk/lib/AST/ExprClassification.cpp Tue Nov 23 14:48:44 2010
@@ -64,7 +64,6 @@
kind = Cl::CL_Void;
}
-#if 0
// Enable this assertion for testing.
switch (kind) {
case Cl::CL_LValue: assert(getValueKind() == VK_LValue); break;
@@ -77,7 +76,6 @@
case Cl::CL_ClassTemporary:
case Cl::CL_PRValue: assert(getValueKind() == VK_RValue); break;
}
-#endif
Cl::ModifiableType modifiable = Cl::CM_Untested;
if (Loc)
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=120055&r1=120054&r2=120055&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov 23 14:48:44 2010
@@ -795,6 +795,12 @@
D, NameInfo, Ty, VK));
}
+static ExprResult
+BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
+ const CXXScopeSpec &SS, FieldDecl *Field,
+ DeclAccessPair FoundDecl,
+ const DeclarationNameInfo &MemberNameInfo);
+
ExprResult
Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
IndirectFieldDecl *IndirectField,
@@ -863,45 +869,29 @@
// Build the implicit member references to the field of the
// anonymous struct/union.
Expr *Result = BaseObjectExpr;
- Qualifiers ResultQuals = BaseQuals;
-
+
IndirectFieldDecl::chain_iterator FI = IndirectField->chain_begin(),
FEnd = IndirectField->chain_end();
-
+
// Skip the first VarDecl if present.
if (BaseObject)
FI++;
for (; FI != FEnd; FI++) {
FieldDecl *Field = cast<FieldDecl>(*FI);
- QualType MemberType = Field->getType();
- Qualifiers MemberTypeQuals =
- Context.getCanonicalType(MemberType).getQualifiers();
-
- // CVR attributes from the base are picked up by members,
- // except that 'mutable' members don't pick up 'const'.
- if (Field->isMutable())
- ResultQuals.removeConst();
- // GC attributes are never picked up by members.
- ResultQuals.removeObjCGCAttr();
+ // FIXME: the first access can be qualified
+ CXXScopeSpec SS;
- // TR 18037 does not allow fields to be declared with address spaces.
- assert(!MemberTypeQuals.hasAddressSpace());
+ // FIXME: these are somewhat meaningless
+ DeclarationNameInfo MemberNameInfo(Field->getDeclName(), Loc);
+ DeclAccessPair FoundDecl = DeclAccessPair::make(Field, Field->getAccess());
+
+ Result = BuildFieldReferenceExpr(*this, Result, BaseObjectIsPointer,
+ SS, Field, FoundDecl, MemberNameInfo)
+ .take();
- Qualifiers NewQuals = ResultQuals + MemberTypeQuals;
- if (NewQuals != MemberTypeQuals)
- MemberType = Context.getQualifiedType(MemberType, NewQuals);
-
- MarkDeclarationReferenced(Loc, *FI);
- PerformObjectMemberConversion(Result, /*FIXME:Qualifier=*/0, *FI, *FI);
- // FIXME: Might this end up being a qualified name?
- Result = new (Context) MemberExpr(Result, BaseObjectIsPointer,
- cast<FieldDecl>(*FI), OpLoc,
- MemberType, VK_LValue,
- Field->isBitField() ?
- OK_BitField : OK_Ordinary);
+ // All the implicit accesses are dot-accesses.
BaseObjectIsPointer = false;
- ResultQuals = NewQuals;
}
return Owned(Result);
@@ -1893,6 +1883,64 @@
TemplateArgs, Ty, VK, OK);
}
+static ExprResult
+BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
+ const CXXScopeSpec &SS, FieldDecl *Field,
+ DeclAccessPair FoundDecl,
+ const DeclarationNameInfo &MemberNameInfo) {
+ // x.a is an l-value if 'a' has a reference type. Otherwise:
+ // x.a is an l-value/x-value/pr-value if the base is (and note
+ // that *x is always an l-value), except that if the base isn't
+ // an ordinary object then we must have an rvalue.
+ ExprValueKind VK = VK_LValue;
+ ExprObjectKind OK = OK_Ordinary;
+ if (!IsArrow) {
+ if (BaseExpr->getObjectKind() == OK_Ordinary)
+ VK = BaseExpr->getValueKind();
+ else
+ VK = VK_RValue;
+ }
+ if (VK != VK_RValue && Field->isBitField())
+ OK = OK_BitField;
+
+ // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
+ QualType MemberType = Field->getType();
+ if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) {
+ MemberType = Ref->getPointeeType();
+ VK = VK_LValue;
+ } else {
+ QualType BaseType = BaseExpr->getType();
+ if (IsArrow) BaseType = BaseType->getAs<PointerType>()->getPointeeType();
+
+ Qualifiers BaseQuals = BaseType.getQualifiers();
+
+ // GC attributes are never picked up by members.
+ BaseQuals.removeObjCGCAttr();
+
+ // CVR attributes from the base are picked up by members,
+ // except that 'mutable' members don't pick up 'const'.
+ if (Field->isMutable()) BaseQuals.removeConst();
+
+ Qualifiers MemberQuals
+ = S.Context.getCanonicalType(MemberType).getQualifiers();
+
+ // TR 18037 does not allow fields to be declared with address spaces.
+ assert(!MemberQuals.hasAddressSpace());
+
+ Qualifiers Combined = BaseQuals + MemberQuals;
+ if (Combined != MemberQuals)
+ MemberType = S.Context.getQualifiedType(MemberType, Combined);
+ }
+
+ S.MarkDeclarationReferenced(MemberNameInfo.getLoc(), Field);
+ if (S.PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(),
+ FoundDecl, Field))
+ return ExprError();
+ return S.Owned(BuildMemberExpr(S.Context, BaseExpr, IsArrow, SS,
+ Field, FoundDecl, MemberNameInfo,
+ MemberType, VK, OK));
+}
+
/// Builds an implicit member access expression. The current context
/// is known to be an instance method, and the given unqualified lookup
/// set is known to contain only instance members, at least one of which
@@ -3262,48 +3310,9 @@
return ExprError();
}
- if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) {
-
- // x.a is an l-value if 'a' has a reference type. Otherwise:
- // x.a is an l-value/x-value/pr-value if the base is (and note
- // that *x is always an l-value), except that if the base isn't
- // an ordinary object then we must have an rvalue.
- ExprValueKind VK = VK_LValue;
- ExprObjectKind OK = OK_Ordinary;
- if (!IsArrow) {
- if (BaseExpr->getObjectKind() == OK_Ordinary)
- VK = BaseExpr->getValueKind();
- else
- VK = VK_RValue;
- }
- if (VK != VK_RValue && FD->isBitField())
- OK = OK_BitField;
-
- // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
- QualType MemberType = FD->getType();
- if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) {
- MemberType = Ref->getPointeeType();
- VK = VK_LValue;
- } else {
- Qualifiers BaseQuals = BaseType.getQualifiers();
- BaseQuals.removeObjCGCAttr();
- if (FD->isMutable()) BaseQuals.removeConst();
-
- Qualifiers MemberQuals
- = Context.getCanonicalType(MemberType).getQualifiers();
-
- Qualifiers Combined = BaseQuals + MemberQuals;
- if (Combined != MemberQuals)
- MemberType = Context.getQualifiedType(MemberType, Combined);
- }
-
- MarkDeclarationReferenced(MemberLoc, FD);
- if (PerformObjectMemberConversion(BaseExpr, Qualifier, FoundDecl, FD))
- return ExprError();
- return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
- FD, FoundDecl, MemberNameInfo,
- MemberType, VK, OK));
- }
+ if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl))
+ return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow,
+ SS, FD, FoundDecl, MemberNameInfo);
if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl))
// We may have found a field within an anonymous union or struct
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=120055&r1=120054&r2=120055&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Nov 23 14:48:44 2010
@@ -3365,9 +3365,17 @@
ClassType.getTypePtr());
CXXScopeSpec SS;
SS.setScopeRep(Qualifier);
+
+ // The actual value-ness of this is unimportant, but for
+ // internal consistency's sake, references to instance methods
+ // are r-values.
+ ExprValueKind VK = VK_LValue;
+ if (isa<CXXMethodDecl>(VD) && cast<CXXMethodDecl>(VD)->isInstance())
+ VK = VK_RValue;
+
ExprResult RefExpr = BuildDeclRefExpr(VD,
VD->getType().getNonReferenceType(),
- VK_LValue,
+ VK,
Loc,
&SS);
if (RefExpr.isInvalid())
More information about the cfe-commits
mailing list