SemaExprCXX.cpp (199512) | SemaExprCXX.cpp (199990) |
---|---|
1//===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 49 unchanged lines hidden (view full) --- 58 QualType T = E->getType(); 59 if (const RecordType *RecordT = T->getAs<RecordType>()) { 60 CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl()); 61 if (RecordD->isPolymorphic()) 62 isUnevaluatedOperand = false; 63 } 64 } 65 | 1//===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 49 unchanged lines hidden (view full) --- 58 QualType T = E->getType(); 59 if (const RecordType *RecordT = T->getAs<RecordType>()) { 60 CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl()); 61 if (RecordD->isPolymorphic()) 62 isUnevaluatedOperand = false; 63 } 64 } 65 |
66 // If this is an unevaluated operand, clear out the set of declaration 67 // references we have been computing. | 66 // If this is an unevaluated operand, clear out the set of 67 // declaration references we have been computing and eliminate any 68 // temporaries introduced in its computation. |
68 if (isUnevaluatedOperand) | 69 if (isUnevaluatedOperand) |
69 PotentiallyReferencedDeclStack.back().clear(); | 70 ExprEvalContexts.back().Context = Unevaluated; |
70 } 71 72 return Owned(new (Context) CXXTypeidExpr(isType, TyOrExpr, 73 TypeInfoType.withConst(), 74 SourceRange(OpLoc, RParenLoc))); 75} 76 77/// ActOnCXXBoolLiteral - Parse {true,false} literals. --- 243 unchanged lines hidden (view full) --- 321 } 322 } 323 324 //FIXME: Store DeclaratorInfo in CXXNew expression. 325 DeclaratorInfo *DInfo = 0; 326 QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo); 327 if (D.isInvalidType()) 328 return ExprError(); | 71 } 72 73 return Owned(new (Context) CXXTypeidExpr(isType, TyOrExpr, 74 TypeInfoType.withConst(), 75 SourceRange(OpLoc, RParenLoc))); 76} 77 78/// ActOnCXXBoolLiteral - Parse {true,false} literals. --- 243 unchanged lines hidden (view full) --- 322 } 323 } 324 325 //FIXME: Store DeclaratorInfo in CXXNew expression. 326 DeclaratorInfo *DInfo = 0; 327 QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo); 328 if (D.isInvalidType()) 329 return ExprError(); |
329 | 330 |
330 return BuildCXXNew(StartLoc, UseGlobal, 331 PlacementLParen, 332 move(PlacementArgs), 333 PlacementRParen, 334 ParenTypeId, 335 AllocType, 336 D.getSourceRange().getBegin(), 337 D.getSourceRange(), --- 51 unchanged lines hidden (view full) --- 389 ImpCastExprToType(ArraySize, Context.getSizeType(), 390 CastExpr::CK_IntegralCast); 391 } 392 393 FunctionDecl *OperatorNew = 0; 394 FunctionDecl *OperatorDelete = 0; 395 Expr **PlaceArgs = (Expr**)PlacementArgs.get(); 396 unsigned NumPlaceArgs = PlacementArgs.size(); | 331 return BuildCXXNew(StartLoc, UseGlobal, 332 PlacementLParen, 333 move(PlacementArgs), 334 PlacementRParen, 335 ParenTypeId, 336 AllocType, 337 D.getSourceRange().getBegin(), 338 D.getSourceRange(), --- 51 unchanged lines hidden (view full) --- 390 ImpCastExprToType(ArraySize, Context.getSizeType(), 391 CastExpr::CK_IntegralCast); 392 } 393 394 FunctionDecl *OperatorNew = 0; 395 FunctionDecl *OperatorDelete = 0; 396 Expr **PlaceArgs = (Expr**)PlacementArgs.get(); 397 unsigned NumPlaceArgs = PlacementArgs.size(); |
397 | 398 |
398 if (!AllocType->isDependentType() && 399 !Expr::hasAnyTypeDependentArguments(PlaceArgs, NumPlaceArgs) && 400 FindAllocationFunctions(StartLoc, 401 SourceRange(PlacementLParen, PlacementRParen), 402 UseGlobal, AllocType, ArraySize, PlaceArgs, 403 NumPlaceArgs, OperatorNew, OperatorDelete)) 404 return ExprError(); | 399 if (!AllocType->isDependentType() && 400 !Expr::hasAnyTypeDependentArguments(PlaceArgs, NumPlaceArgs) && 401 FindAllocationFunctions(StartLoc, 402 SourceRange(PlacementLParen, PlacementRParen), 403 UseGlobal, AllocType, ArraySize, PlaceArgs, 404 NumPlaceArgs, OperatorNew, OperatorDelete)) 405 return ExprError(); |
405 | 406 llvm::SmallVector<Expr *, 8> AllPlaceArgs; 407 if (OperatorNew) { 408 // Add default arguments, if any. 409 const FunctionProtoType *Proto = 410 OperatorNew->getType()->getAs<FunctionProtoType>(); 411 VariadicCallType CallType = 412 Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply; 413 bool Invalid = GatherArgumentsForCall(PlacementLParen, OperatorNew, 414 Proto, 1, PlaceArgs, NumPlaceArgs, 415 AllPlaceArgs, CallType); 416 if (Invalid) 417 return ExprError(); 418 419 NumPlaceArgs = AllPlaceArgs.size(); 420 if (NumPlaceArgs > 0) 421 PlaceArgs = &AllPlaceArgs[0]; 422 } 423 |
406 bool Init = ConstructorLParen.isValid(); 407 // --- Choosing a constructor --- 408 // C++ 5.3.4p15 409 // 1) If T is a POD and there's no initializer (ConstructorLParen is invalid) 410 // the object is not initialized. If the object, or any part of it, is 411 // const-qualified, it's an error. 412 // 2) If T is a POD and there's an empty initializer, the object is value- 413 // initialized. --- 183 unchanged lines hidden (view full) --- 597 OverloadCandidateSet::iterator Best; 598 switch(BestViableFunction(Candidates, StartLoc, Best)) { 599 case OR_Success: { 600 // Got one! 601 FunctionDecl *FnDecl = Best->Function; 602 // The first argument is size_t, and the first parameter must be size_t, 603 // too. This is checked on declaration and can be assumed. (It can't be 604 // asserted on, though, since invalid decls are left in there.) | 424 bool Init = ConstructorLParen.isValid(); 425 // --- Choosing a constructor --- 426 // C++ 5.3.4p15 427 // 1) If T is a POD and there's no initializer (ConstructorLParen is invalid) 428 // the object is not initialized. If the object, or any part of it, is 429 // const-qualified, it's an error. 430 // 2) If T is a POD and there's an empty initializer, the object is value- 431 // initialized. --- 183 unchanged lines hidden (view full) --- 615 OverloadCandidateSet::iterator Best; 616 switch(BestViableFunction(Candidates, StartLoc, Best)) { 617 case OR_Success: { 618 // Got one! 619 FunctionDecl *FnDecl = Best->Function; 620 // The first argument is size_t, and the first parameter must be size_t, 621 // too. This is checked on declaration and can be assumed. (It can't be 622 // asserted on, though, since invalid decls are left in there.) |
605 for (unsigned i = 0; i < NumArgs; ++i) { | 623 // Whatch out for variadic allocator function. 624 unsigned NumArgsInFnDecl = FnDecl->getNumParams(); 625 for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) { |
606 // FIXME: Passing word to diagnostic. 607 if (PerformCopyInitialization(Args[i], 608 FnDecl->getParamDecl(i)->getType(), 609 "passing")) 610 return true; 611 } 612 Operator = FnDecl; 613 return false; --- 208 unchanged lines hidden (view full) --- 822 823 Expr *Ex = (Expr *)Operand.get(); 824 if (!Ex->isTypeDependent()) { 825 QualType Type = Ex->getType(); 826 827 if (const RecordType *Record = Type->getAs<RecordType>()) { 828 llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions; 829 CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); | 626 // FIXME: Passing word to diagnostic. 627 if (PerformCopyInitialization(Args[i], 628 FnDecl->getParamDecl(i)->getType(), 629 "passing")) 630 return true; 631 } 632 Operator = FnDecl; 633 return false; --- 208 unchanged lines hidden (view full) --- 842 843 Expr *Ex = (Expr *)Operand.get(); 844 if (!Ex->isTypeDependent()) { 845 QualType Type = Ex->getType(); 846 847 if (const RecordType *Record = Type->getAs<RecordType>()) { 848 llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions; 849 CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); |
830 OverloadedFunctionDecl *Conversions = 831 RD->getVisibleConversionFunctions(); | 850 const UnresolvedSet *Conversions = RD->getVisibleConversionFunctions(); |
832 | 851 |
833 for (OverloadedFunctionDecl::function_iterator 834 Func = Conversions->function_begin(), 835 FuncEnd = Conversions->function_end(); 836 Func != FuncEnd; ++Func) { | 852 for (UnresolvedSet::iterator I = Conversions->begin(), 853 E = Conversions->end(); I != E; ++I) { |
837 // Skip over templated conversion functions; they aren't considered. | 854 // Skip over templated conversion functions; they aren't considered. |
838 if (isa<FunctionTemplateDecl>(*Func)) | 855 if (isa<FunctionTemplateDecl>(*I)) |
839 continue; 840 | 856 continue; 857 |
841 CXXConversionDecl *Conv = cast<CXXConversionDecl>(*Func); | 858 CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I); |
842 843 QualType ConvType = Conv->getConversionType().getNonReferenceType(); 844 if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>()) 845 if (ConvPtrType->getPointeeType()->isObjectType()) 846 ObjectPtrConversions.push_back(Conv); 847 } 848 if (ObjectPtrConversions.size() == 1) { 849 // We have a single conversion to a pointer-to-object type. Perform --- 72 unchanged lines hidden (view full) --- 922 // FIXME: Check access and ambiguity of operator delete and destructor. 923 } 924 925 Operand.release(); 926 return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm, 927 OperatorDelete, Ex, StartLoc)); 928} 929 | 859 860 QualType ConvType = Conv->getConversionType().getNonReferenceType(); 861 if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>()) 862 if (ConvPtrType->getPointeeType()->isObjectType()) 863 ObjectPtrConversions.push_back(Conv); 864 } 865 if (ObjectPtrConversions.size() == 1) { 866 // We have a single conversion to a pointer-to-object type. Perform --- 72 unchanged lines hidden (view full) --- 939 // FIXME: Check access and ambiguity of operator delete and destructor. 940 } 941 942 Operand.release(); 943 return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm, 944 OperatorDelete, Ex, StartLoc)); 945} 946 |
947/// \brief Check the use of the given variable as a C++ condition in an if, 948/// while, do-while, or switch statement. 949Action::OwningExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar) { 950 QualType T = ConditionVar->getType(); 951 952 // C++ [stmt.select]p2: 953 // The declarator shall not specify a function or an array. 954 if (T->isFunctionType()) 955 return ExprError(Diag(ConditionVar->getLocation(), 956 diag::err_invalid_use_of_function_type) 957 << ConditionVar->getSourceRange()); 958 else if (T->isArrayType()) 959 return ExprError(Diag(ConditionVar->getLocation(), 960 diag::err_invalid_use_of_array_type) 961 << ConditionVar->getSourceRange()); |
|
930 | 962 |
931/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a 932/// C++ if/switch/while/for statement. 933/// e.g: "if (int x = f()) {...}" 934Action::OwningExprResult 935Sema::ActOnCXXConditionDeclarationExpr(Scope *S, SourceLocation StartLoc, 936 Declarator &D, 937 SourceLocation EqualLoc, 938 ExprArg AssignExprVal) { 939 assert(AssignExprVal.get() && "Null assignment expression"); 940 941 // C++ 6.4p2: 942 // The declarator shall not specify a function or an array. 943 // The type-specifier-seq shall not contain typedef and shall not declare a 944 // new class or enumeration. 945 946 assert(D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef && 947 "Parser allowed 'typedef' as storage class of condition decl."); 948 949 // FIXME: Store DeclaratorInfo in the expression. 950 DeclaratorInfo *DInfo = 0; 951 TagDecl *OwnedTag = 0; 952 QualType Ty = GetTypeForDeclarator(D, S, &DInfo, &OwnedTag); 953 954 if (Ty->isFunctionType()) { // The declarator shall not specify a function... 955 // We exit without creating a CXXConditionDeclExpr because a FunctionDecl 956 // would be created and CXXConditionDeclExpr wants a VarDecl. 957 return ExprError(Diag(StartLoc, diag::err_invalid_use_of_function_type) 958 << SourceRange(StartLoc, EqualLoc)); 959 } else if (Ty->isArrayType()) { // ...or an array. 960 Diag(StartLoc, diag::err_invalid_use_of_array_type) 961 << SourceRange(StartLoc, EqualLoc); 962 } else if (OwnedTag && OwnedTag->isDefinition()) { 963 // The type-specifier-seq shall not declare a new class or enumeration. 964 Diag(OwnedTag->getLocation(), diag::err_type_defined_in_condition); 965 } 966 967 DeclPtrTy Dcl = ActOnDeclarator(S, D); 968 if (!Dcl) 969 return ExprError(); 970 AddInitializerToDecl(Dcl, move(AssignExprVal), /*DirectInit=*/false); 971 972 // Mark this variable as one that is declared within a conditional. 973 // We know that the decl had to be a VarDecl because that is the only type of 974 // decl that can be assigned and the grammar requires an '='. 975 VarDecl *VD = cast<VarDecl>(Dcl.getAs<Decl>()); 976 VD->setDeclaredInCondition(true); 977 return Owned(new (Context) CXXConditionDeclExpr(StartLoc, EqualLoc, VD)); | 963 return Owned(DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar, 964 ConditionVar->getLocation(), 965 ConditionVar->getType().getNonReferenceType())); |
978} 979 980/// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid. 981bool Sema::CheckCXXBooleanCondition(Expr *&CondExpr) { 982 // C++ 6.4p4: 983 // The value of a condition that is an initialized declaration in a statement 984 // other than a switch statement is the value of the declared variable 985 // implicitly converted to type bool. If that conversion is ill-formed, the --- 137 unchanged lines hidden (view full) --- 1123 // If the user-defined conversion is specified by a conversion function, 1124 // the initial standard conversion sequence converts the source type to 1125 // the implicit object parameter of the conversion function. 1126 BeforeToType = Context.getTagDeclType(Conv->getParent()); 1127 } else if (const CXXConstructorDecl *Ctor = 1128 dyn_cast<CXXConstructorDecl>(FD)) { 1129 CastKind = CastExpr::CK_ConstructorConversion; 1130 // Do no conversion if dealing with ... for the first conversion. | 966} 967 968/// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid. 969bool Sema::CheckCXXBooleanCondition(Expr *&CondExpr) { 970 // C++ 6.4p4: 971 // The value of a condition that is an initialized declaration in a statement 972 // other than a switch statement is the value of the declared variable 973 // implicitly converted to type bool. If that conversion is ill-formed, the --- 137 unchanged lines hidden (view full) --- 1111 // If the user-defined conversion is specified by a conversion function, 1112 // the initial standard conversion sequence converts the source type to 1113 // the implicit object parameter of the conversion function. 1114 BeforeToType = Context.getTagDeclType(Conv->getParent()); 1115 } else if (const CXXConstructorDecl *Ctor = 1116 dyn_cast<CXXConstructorDecl>(FD)) { 1117 CastKind = CastExpr::CK_ConstructorConversion; 1118 // Do no conversion if dealing with ... for the first conversion. |
1131 if (!ICS.UserDefined.EllipsisConversion) | 1119 if (!ICS.UserDefined.EllipsisConversion) { |
1132 // If the user-defined conversion is specified by a constructor, the 1133 // initial standard conversion sequence converts the source type to the 1134 // type required by the argument of the constructor | 1120 // If the user-defined conversion is specified by a constructor, the 1121 // initial standard conversion sequence converts the source type to the 1122 // type required by the argument of the constructor |
1135 BeforeToType = Ctor->getParamDecl(0)->getType(); | 1123 BeforeToType = Ctor->getParamDecl(0)->getType().getNonReferenceType(); 1124 } |
1136 } 1137 else 1138 assert(0 && "Unknown conversion function kind!"); 1139 // Whatch out for elipsis conversion. 1140 if (!ICS.UserDefined.EllipsisConversion) { 1141 if (PerformImplicitConversion(From, BeforeToType, 1142 ICS.UserDefined.Before, "converting", 1143 IgnoreBaseAccess)) 1144 return true; 1145 } 1146 1147 OwningExprResult CastArg 1148 = BuildCXXCastArgument(From->getLocStart(), 1149 ToType.getNonReferenceType(), 1150 CastKind, cast<CXXMethodDecl>(FD), 1151 Owned(From)); 1152 1153 if (CastArg.isInvalid()) 1154 return true; | 1125 } 1126 else 1127 assert(0 && "Unknown conversion function kind!"); 1128 // Whatch out for elipsis conversion. 1129 if (!ICS.UserDefined.EllipsisConversion) { 1130 if (PerformImplicitConversion(From, BeforeToType, 1131 ICS.UserDefined.Before, "converting", 1132 IgnoreBaseAccess)) 1133 return true; 1134 } 1135 1136 OwningExprResult CastArg 1137 = BuildCXXCastArgument(From->getLocStart(), 1138 ToType.getNonReferenceType(), 1139 CastKind, cast<CXXMethodDecl>(FD), 1140 Owned(From)); 1141 1142 if (CastArg.isInvalid()) 1143 return true; |
1155 | 1144 1145 From = CastArg.takeAs<Expr>(); 1146 1147 // FIXME: This and the following if statement shouldn't be necessary, but 1148 // there's some nasty stuff involving MaybeBindToTemporary going on here. |
1156 if (ICS.UserDefined.After.Second == ICK_Derived_To_Base && 1157 ICS.UserDefined.After.CopyConstructor) { | 1149 if (ICS.UserDefined.After.Second == ICK_Derived_To_Base && 1150 ICS.UserDefined.After.CopyConstructor) { |
1158 From = CastArg.takeAs<Expr>(); | |
1159 return BuildCXXDerivedToBaseExpr(From, CastKind, ICS, Flavor); 1160 } | 1151 return BuildCXXDerivedToBaseExpr(From, CastKind, ICS, Flavor); 1152 } |
1161 1162 if (ICS.UserDefined.After.Second == ICK_Pointer_Member && 1163 ToType.getNonReferenceType()->isMemberFunctionPointerType()) 1164 CastKind = CastExpr::CK_BaseToDerivedMemberPointer; 1165 1166 From = new (Context) ImplicitCastExpr(ToType.getNonReferenceType(), 1167 CastKind, CastArg.takeAs<Expr>(), 1168 ToType->isLValueReferenceType()); 1169 return false; | 1153 1154 if (ICS.UserDefined.After.CopyConstructor) { 1155 From = new (Context) ImplicitCastExpr(ToType.getNonReferenceType(), 1156 CastKind, From, 1157 ToType->isLValueReferenceType()); 1158 return false; 1159 } 1160 1161 return PerformImplicitConversion(From, ToType, ICS.UserDefined.After, 1162 "converting", IgnoreBaseAccess); |
1170 } 1171 1172 case ImplicitConversionSequence::EllipsisConversion: 1173 assert(false && "Cannot perform an ellipsis conversion"); 1174 return false; 1175 1176 case ImplicitConversionSequence::BadConversion: 1177 return true; --- 150 unchanged lines hidden (view full) --- 1328 CastExpr::CastKind Kind = CastExpr::CK_Unknown; 1329 if (CheckMemberPointerConversion(From, ToType, Kind, IgnoreBaseAccess)) 1330 return true; 1331 if (CheckExceptionSpecCompatibility(From, ToType)) 1332 return true; 1333 ImpCastExprToType(From, ToType, Kind); 1334 break; 1335 } | 1163 } 1164 1165 case ImplicitConversionSequence::EllipsisConversion: 1166 assert(false && "Cannot perform an ellipsis conversion"); 1167 return false; 1168 1169 case ImplicitConversionSequence::BadConversion: 1170 return true; --- 150 unchanged lines hidden (view full) --- 1321 CastExpr::CastKind Kind = CastExpr::CK_Unknown; 1322 if (CheckMemberPointerConversion(From, ToType, Kind, IgnoreBaseAccess)) 1323 return true; 1324 if (CheckExceptionSpecCompatibility(From, ToType)) 1325 return true; 1326 ImpCastExprToType(From, ToType, Kind); 1327 break; 1328 } |
1336 case ICK_Boolean_Conversion: 1337 ImpCastExprToType(From, Context.BoolTy, CastExpr::CK_Unknown); | 1329 case ICK_Boolean_Conversion: { 1330 CastExpr::CastKind Kind = CastExpr::CK_Unknown; 1331 if (FromType->isMemberPointerType()) 1332 Kind = CastExpr::CK_MemberPointerToBoolean; 1333 1334 ImpCastExprToType(From, Context.BoolTy, Kind); |
1338 break; | 1335 break; |
1336 } |
|
1339 1340 case ICK_Derived_To_Base: 1341 if (CheckDerivedToBaseConversion(From->getType(), 1342 ToType.getNonReferenceType(), 1343 From->getLocStart(), 1344 From->getSourceRange(), 1345 IgnoreBaseAccess)) 1346 return true; --- 779 unchanged lines hidden (view full) --- 2126 CanQualType CBaseType = Context.getCanonicalType(BaseType); 2127 if (!CTypes.insert(CBaseType)) { 2128 Diag(OpLoc, diag::err_operator_arrow_circular); 2129 for (unsigned i = 0; i < Locations.size(); i++) 2130 Diag(Locations[i], diag::note_declared_at); 2131 return ExprError(); 2132 } 2133 } | 1337 1338 case ICK_Derived_To_Base: 1339 if (CheckDerivedToBaseConversion(From->getType(), 1340 ToType.getNonReferenceType(), 1341 From->getLocStart(), 1342 From->getSourceRange(), 1343 IgnoreBaseAccess)) 1344 return true; --- 779 unchanged lines hidden (view full) --- 2124 CanQualType CBaseType = Context.getCanonicalType(BaseType); 2125 if (!CTypes.insert(CBaseType)) { 2126 Diag(OpLoc, diag::err_operator_arrow_circular); 2127 for (unsigned i = 0; i < Locations.size(); i++) 2128 Diag(Locations[i], diag::note_declared_at); 2129 return ExprError(); 2130 } 2131 } |
2132 2133 if (BaseType->isPointerType()) 2134 BaseType = BaseType->getPointeeType(); |
|
2134 } 2135 | 2135 } 2136 |
2136 if (BaseType->isPointerType()) 2137 BaseType = BaseType->getPointeeType(); 2138 | |
2139 // We could end up with various non-record types here, such as extended 2140 // vector types or Objective-C interfaces. Just return early and let 2141 // ActOnMemberReferenceExpr do the work. 2142 if (!BaseType->isRecordType()) { 2143 // C++ [basic.lookup.classref]p2: 2144 // [...] If the type of the object expression is of pointer to scalar 2145 // type, the unqualified-id is looked up in the context of the complete 2146 // postfix-expression. --- 23 unchanged lines hidden (view full) --- 2170 new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method, 2171 SourceLocation(), Method->getType()); 2172 QualType ResultType; 2173 if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(Method)) 2174 ResultType = Conv->getConversionType().getNonReferenceType(); 2175 else 2176 ResultType = Method->getResultType().getNonReferenceType(); 2177 | 2137 // We could end up with various non-record types here, such as extended 2138 // vector types or Objective-C interfaces. Just return early and let 2139 // ActOnMemberReferenceExpr do the work. 2140 if (!BaseType->isRecordType()) { 2141 // C++ [basic.lookup.classref]p2: 2142 // [...] If the type of the object expression is of pointer to scalar 2143 // type, the unqualified-id is looked up in the context of the complete 2144 // postfix-expression. --- 23 unchanged lines hidden (view full) --- 2168 new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method, 2169 SourceLocation(), Method->getType()); 2170 QualType ResultType; 2171 if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(Method)) 2172 ResultType = Conv->getConversionType().getNonReferenceType(); 2173 else 2174 ResultType = Method->getResultType().getNonReferenceType(); 2175 |
2178 CXXMemberCallExpr *CE = 2179 new (Context) CXXMemberCallExpr(Context, ME, 0, 0, 2180 ResultType, 2181 Exp->getLocEnd()); | 2176 MarkDeclarationReferenced(Exp->getLocStart(), Method); 2177 CXXMemberCallExpr *CE = 2178 new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType, 2179 Exp->getLocEnd()); |
2182 return CE; 2183} 2184 2185Sema::OwningExprResult Sema::BuildCXXCastArgument(SourceLocation CastLoc, 2186 QualType Ty, 2187 CastExpr::CastKind Kind, 2188 CXXMethodDecl *Method, 2189 ExprArg Arg) { --- 43 unchanged lines hidden (view full) --- 2233} 2234 2235/// \brief Determine whether a reference to the given declaration in the 2236/// current context is an implicit member access 2237/// (C++ [class.mfct.non-static]p2). 2238/// 2239/// FIXME: Should Objective-C also use this approach? 2240/// | 2180 return CE; 2181} 2182 2183Sema::OwningExprResult Sema::BuildCXXCastArgument(SourceLocation CastLoc, 2184 QualType Ty, 2185 CastExpr::CastKind Kind, 2186 CXXMethodDecl *Method, 2187 ExprArg Arg) { --- 43 unchanged lines hidden (view full) --- 2231} 2232 2233/// \brief Determine whether a reference to the given declaration in the 2234/// current context is an implicit member access 2235/// (C++ [class.mfct.non-static]p2). 2236/// 2237/// FIXME: Should Objective-C also use this approach? 2238/// |
2241/// \param SS if non-NULL, the C++ nested-name-specifier that precedes the 2242/// name of the declaration referenced. 2243/// | |
2244/// \param D the declaration being referenced from the current scope. 2245/// 2246/// \param NameLoc the location of the name in the source. 2247/// 2248/// \param ThisType if the reference to this declaration is an implicit member 2249/// access, will be set to the type of the "this" pointer to be used when 2250/// building that implicit member access. 2251/// | 2239/// \param D the declaration being referenced from the current scope. 2240/// 2241/// \param NameLoc the location of the name in the source. 2242/// 2243/// \param ThisType if the reference to this declaration is an implicit member 2244/// access, will be set to the type of the "this" pointer to be used when 2245/// building that implicit member access. 2246/// |
2252/// \param MemberType if the reference to this declaration is an implicit 2253/// member access, will be set to the type of the member being referenced 2254/// (for use at the type of the resulting member access expression). 2255/// | |
2256/// \returns true if this is an implicit member reference (in which case 2257/// \p ThisType and \p MemberType will be set), or false if it is not an 2258/// implicit member reference. | 2247/// \returns true if this is an implicit member reference (in which case 2248/// \p ThisType and \p MemberType will be set), or false if it is not an 2249/// implicit member reference. |
2259bool Sema::isImplicitMemberReference(const CXXScopeSpec *SS, NamedDecl *D, 2260 SourceLocation NameLoc, QualType &ThisType, 2261 QualType &MemberType) { | 2250bool Sema::isImplicitMemberReference(const LookupResult &R, 2251 QualType &ThisType) { |
2262 // If this isn't a C++ method, then it isn't an implicit member reference. 2263 CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext); 2264 if (!MD || MD->isStatic()) 2265 return false; 2266 2267 // C++ [class.mfct.nonstatic]p2: 2268 // [...] if name lookup (3.4.1) resolves the name in the 2269 // id-expression to a nonstatic nontype member of class X or of 2270 // a base class of X, the id-expression is transformed into a 2271 // class member access expression (5.2.5) using (*this) (9.3.2) 2272 // as the postfix-expression to the left of the '.' operator. 2273 DeclContext *Ctx = 0; | 2252 // If this isn't a C++ method, then it isn't an implicit member reference. 2253 CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext); 2254 if (!MD || MD->isStatic()) 2255 return false; 2256 2257 // C++ [class.mfct.nonstatic]p2: 2258 // [...] if name lookup (3.4.1) resolves the name in the 2259 // id-expression to a nonstatic nontype member of class X or of 2260 // a base class of X, the id-expression is transformed into a 2261 // class member access expression (5.2.5) using (*this) (9.3.2) 2262 // as the postfix-expression to the left of the '.' operator. 2263 DeclContext *Ctx = 0; |
2274 if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { | 2264 if (R.isUnresolvableResult()) { 2265 // FIXME: this is just picking one at random 2266 Ctx = R.getRepresentativeDecl()->getDeclContext(); 2267 } else if (FieldDecl *FD = R.getAsSingle<FieldDecl>()) { |
2275 Ctx = FD->getDeclContext(); | 2268 Ctx = FD->getDeclContext(); |
2276 MemberType = FD->getType(); 2277 2278 if (const ReferenceType *RefType = MemberType->getAs<ReferenceType>()) 2279 MemberType = RefType->getPointeeType(); 2280 else if (!FD->isMutable()) 2281 MemberType 2282 = Context.getQualifiedType(MemberType, 2283 Qualifiers::fromCVRMask(MD->getTypeQualifiers())); | |
2284 } else { | 2269 } else { |
2285 for (OverloadIterator Ovl(D), OvlEnd; Ovl != OvlEnd; ++Ovl) { 2286 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Ovl); | 2270 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { 2271 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*I); |
2287 FunctionTemplateDecl *FunTmpl = 0; | 2272 FunctionTemplateDecl *FunTmpl = 0; |
2288 if (!Method && (FunTmpl = dyn_cast<FunctionTemplateDecl>(*Ovl))) | 2273 if (!Method && (FunTmpl = dyn_cast<FunctionTemplateDecl>(*I))) |
2289 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); 2290 2291 // FIXME: Do we have to know if there are explicit template arguments? 2292 if (Method && !Method->isStatic()) { 2293 Ctx = Method->getParent(); | 2274 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); 2275 2276 // FIXME: Do we have to know if there are explicit template arguments? 2277 if (Method && !Method->isStatic()) { 2278 Ctx = Method->getParent(); |
2294 if (isa<CXXMethodDecl>(D) && !FunTmpl) 2295 MemberType = Method->getType(); 2296 else 2297 MemberType = Context.OverloadTy; | |
2298 break; 2299 } 2300 } 2301 } 2302 2303 if (!Ctx || !Ctx->isRecord()) 2304 return false; 2305 2306 // Determine whether the declaration(s) we found are actually in a base 2307 // class. If not, this isn't an implicit member reference. 2308 ThisType = MD->getThisType(Context); | 2279 break; 2280 } 2281 } 2282 } 2283 2284 if (!Ctx || !Ctx->isRecord()) 2285 return false; 2286 2287 // Determine whether the declaration(s) we found are actually in a base 2288 // class. If not, this isn't an implicit member reference. 2289 ThisType = MD->getThisType(Context); |
2290 2291 // FIXME: this doesn't really work for overloaded lookups. |
|
2309 | 2292 |
2310 // If the type of "this" is dependent, we can't tell if the member is in a 2311 // base class or not, so treat this as a dependent implicit member reference. 2312 if (ThisType->isDependentType()) 2313 return true; 2314 | |
2315 QualType CtxType = Context.getTypeDeclType(cast<CXXRecordDecl>(Ctx)); 2316 QualType ClassType 2317 = Context.getTypeDeclType(cast<CXXRecordDecl>(MD->getParent())); 2318 return Context.hasSameType(CtxType, ClassType) || 2319 IsDerivedFrom(ClassType, CtxType); 2320} 2321 | 2293 QualType CtxType = Context.getTypeDeclType(cast<CXXRecordDecl>(Ctx)); 2294 QualType ClassType 2295 = Context.getTypeDeclType(cast<CXXRecordDecl>(MD->getParent())); 2296 return Context.hasSameType(CtxType, ClassType) || 2297 IsDerivedFrom(ClassType, CtxType); 2298} 2299 |