diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 64 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 39 |
2 files changed, 63 insertions, 40 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 51e4e05eec8..7fafb145916 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1244,24 +1244,44 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, << &Member << BaseExpr->getSourceRange(); } - FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first); - if (!MemberDecl) { - unsigned DiagID = PP.getDiagnostics().getCustomDiagID(Diagnostic::Error, - "Clang only supports references to members"); - return Diag(MemberLoc, DiagID); - } - - // Figure out the type of the member; see C99 6.5.2.3p3 - // FIXME: Handle address space modifiers - QualType MemberType = MemberDecl->getType(); - unsigned combinedQualifiers = - MemberType.getCVRQualifiers() | BaseType.getCVRQualifiers(); - if (MemberDecl->isMutable()) - combinedQualifiers &= ~QualType::Const; - MemberType = MemberType.getQualifiedType(combinedQualifiers); + if (FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first)) { + // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref] + // FIXME: Handle address space modifiers + QualType MemberType = MemberDecl->getType(); + if (const ReferenceType *Ref = MemberType->getAsReferenceType()) + MemberType = Ref->getPointeeType(); + else { + unsigned combinedQualifiers = + MemberType.getCVRQualifiers() | BaseType.getCVRQualifiers(); + if (MemberDecl->isMutable()) + combinedQualifiers &= ~QualType::Const; + MemberType = MemberType.getQualifiedType(combinedQualifiers); + } - return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberDecl, - MemberLoc, MemberType); + return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberDecl, + MemberLoc, MemberType); + } else if (CXXClassVarDecl *Var = dyn_cast<CXXClassVarDecl>(*Lookup.first)) + return new MemberExpr(BaseExpr, OpKind == tok::arrow, Var, MemberLoc, + Var->getType().getNonReferenceType()); + else if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(*Lookup.first)) + return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberFn, MemberLoc, + MemberFn->getType()); + else if (OverloadedFunctionDecl *Ovl + = dyn_cast<OverloadedFunctionDecl>(*Lookup.first)) + return new MemberExpr(BaseExpr, OpKind == tok::arrow, Ovl, MemberLoc, + Context.OverloadTy); + else if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(*Lookup.first)) + return new MemberExpr(BaseExpr, OpKind == tok::arrow, Enum, MemberLoc, + Enum->getType()); + else if (isa<TypeDecl>(*Lookup.first)) + return Diag(MemberLoc, diag::err_typecheck_member_reference_type) + << DeclarationName(&Member) << int(OpKind == tok::arrow); + + // We found a declaration kind that we didn't expect. This is a + // generic error message that tells the user that she can't refer + // to this member with '.' or '->'. + return Diag(MemberLoc, diag::err_typecheck_member_reference_unknown) + << DeclarationName(&Member) << int(OpKind == tok::arrow); } // Handle access to Objective-C instance variables, such as "Obj->ivar" and @@ -2920,10 +2940,12 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { return QualType(); } } else if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(op)) { // C99 6.5.3.2p1 - if (MemExpr->getMemberDecl()->isBitField()) { - Diag(OpLoc, diag::err_typecheck_address_of) - << "bit-field" << op->getSourceRange(); - return QualType(); + if (FieldDecl *Field = dyn_cast<FieldDecl>(MemExpr->getMemberDecl())) { + if (Field->isBitField()) { + Diag(OpLoc, diag::err_typecheck_address_of) + << "bit-field" << op->getSourceRange(); + return QualType(); + } } // Check for Apple extension for accessing vector components. } else if (isa<ArraySubscriptExpr>(op) && diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c719f56c4ee..fe4b763502a 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -666,26 +666,27 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) // other value of that type for promotion purposes (C++ 4.5p3). if (MemberExpr *MemRef = dyn_cast<MemberExpr>(From)) { using llvm::APSInt; - FieldDecl *MemberDecl = MemRef->getMemberDecl(); - APSInt BitWidth; - if (MemberDecl->isBitField() && - FromType->isIntegralType() && !FromType->isEnumeralType() && - From->isIntegerConstantExpr(BitWidth, Context)) { - APSInt ToSize(Context.getTypeSize(ToType)); - - // Are we promoting to an int from a bitfield that fits in an int? - if (BitWidth < ToSize || - (FromType->isSignedIntegerType() && BitWidth <= ToSize)) { - return To->getKind() == BuiltinType::Int; - } - - // Are we promoting to an unsigned int from an unsigned bitfield - // that fits into an unsigned int? - if (FromType->isUnsignedIntegerType() && BitWidth <= ToSize) { - return To->getKind() == BuiltinType::UInt; + if (FieldDecl *MemberDecl = dyn_cast<FieldDecl>(MemRef->getMemberDecl())) { + APSInt BitWidth; + if (MemberDecl->isBitField() && + FromType->isIntegralType() && !FromType->isEnumeralType() && + From->isIntegerConstantExpr(BitWidth, Context)) { + APSInt ToSize(Context.getTypeSize(ToType)); + + // Are we promoting to an int from a bitfield that fits in an int? + if (BitWidth < ToSize || + (FromType->isSignedIntegerType() && BitWidth <= ToSize)) { + return To->getKind() == BuiltinType::Int; + } + + // Are we promoting to an unsigned int from an unsigned bitfield + // that fits into an unsigned int? + if (FromType->isUnsignedIntegerType() && BitWidth <= ToSize) { + return To->getKind() == BuiltinType::UInt; + } + + return false; } - - return false; } } |