diff options
| author | 2019-01-27 16:42:12 +0000 | |
|---|---|---|
| committer | 2019-01-27 16:42:12 +0000 | |
| commit | b773203fb58f3ef282fb69c832d8710cab5bc82d (patch) | |
| tree | e75913f147570fbd75169647b144df85b88a038c /gnu/llvm/tools/clang/lib/Sema/SemaExprMember.cpp | |
| parent | tweak errno in previous (diff) | |
| download | wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip | |
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Sema/SemaExprMember.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Sema/SemaExprMember.cpp | 186 |
1 files changed, 78 insertions, 108 deletions
diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaExprMember.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaExprMember.cpp index f57f79e62ef..e6d2b5068fd 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaExprMember.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaExprMember.cpp @@ -120,7 +120,7 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, // member reference. if (Classes.empty()) return IMA_Static; - + // C++11 [expr.prim.general]p12: // An id-expression that denotes a non-static data member or non-static // member function of a class can only be used: @@ -166,7 +166,7 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, else contextClass = cast<CXXRecordDecl>(DC); - // [class.mfct.non-static]p3: + // [class.mfct.non-static]p3: // ...is used in the body of a non-static member function of class X, // if name lookup (3.4.1) resolves the name in the id-expression to a // non-static non-type member of some class C [...] @@ -417,14 +417,14 @@ CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK, QualType VT = S.Context.getExtVectorType(vecType->getElementType(), CompSize); // Now look up the TypeDefDecl from the vector type. Without this, // diagostics look bad. We want extended vector types to appear built-in. - for (Sema::ExtVectorDeclsType::iterator + for (Sema::ExtVectorDeclsType::iterator I = S.ExtVectorDecls.begin(S.getExternalSource()), - E = S.ExtVectorDecls.end(); + E = S.ExtVectorDecls.end(); I != E; ++I) { if ((*I)->getUnderlyingType() == VT) return S.Context.getTypedefType(*I); } - + return VT; // should never get here (a typedef type should always be found). } @@ -640,6 +640,7 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, const RecordType *RTy, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, bool HasTemplateArgs, + SourceLocation TemplateKWLoc, TypoExpr *&TE) { SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange(); RecordDecl *RDecl = RTy->getDecl(); @@ -649,13 +650,13 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, BaseRange)) return true; - if (HasTemplateArgs) { + if (HasTemplateArgs || TemplateKWLoc.isValid()) { // LookupTemplateName doesn't expect these both to exist simultaneously. QualType ObjectType = SS.isSet() ? QualType() : QualType(RTy, 0); bool MOUS; - SemaRef.LookupTemplateName(R, nullptr, SS, ObjectType, false, MOUS); - return false; + return SemaRef.LookupTemplateName(R, nullptr, SS, ObjectType, false, MOUS, + TemplateKWLoc); } DeclContext *DC = RDecl; @@ -733,7 +734,8 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, ExprResult &BaseExpr, bool &IsArrow, SourceLocation OpLoc, CXXScopeSpec &SS, - Decl *ObjCImpDecl, bool HasTemplateArgs); + Decl *ObjCImpDecl, bool HasTemplateArgs, + SourceLocation TemplateKWLoc); ExprResult Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, @@ -759,9 +761,9 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, TypoExpr *TE = nullptr; QualType RecordTy = BaseType; if (IsArrow) RecordTy = RecordTy->getAs<PointerType>()->getPointeeType(); - if (LookupMemberExprInRecord(*this, R, nullptr, - RecordTy->getAs<RecordType>(), OpLoc, IsArrow, - SS, TemplateArgs != nullptr, TE)) + if (LookupMemberExprInRecord( + *this, R, nullptr, RecordTy->getAs<RecordType>(), OpLoc, IsArrow, + SS, TemplateArgs != nullptr, TemplateKWLoc, TE)) return ExprError(); if (TE) return TE; @@ -769,10 +771,10 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, // Explicit member accesses. } else { ExprResult BaseResult = Base; - ExprResult Result = LookupMemberExpr( - *this, R, BaseResult, IsArrow, OpLoc, SS, - ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr, - TemplateArgs != nullptr); + ExprResult Result = + LookupMemberExpr(*this, R, BaseResult, IsArrow, OpLoc, SS, + ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr, + TemplateArgs != nullptr, TemplateKWLoc); if (BaseResult.isInvalid()) return ExprError(); @@ -802,95 +804,61 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, Expr *baseObjectExpr, SourceLocation opLoc) { // First, build the expression that refers to the base object. - - bool baseObjectIsPointer = false; - Qualifiers baseQuals; - + // Case 1: the base of the indirect field is not a field. VarDecl *baseVariable = indirectField->getVarDecl(); CXXScopeSpec EmptySS; if (baseVariable) { assert(baseVariable->getType()->isRecordType()); - + // In principle we could have a member access expression that // accesses an anonymous struct/union that's a static member of // the base object's class. However, under the current standard, // static data members cannot be anonymous structs or unions. // Supporting this is as easy as building a MemberExpr here. assert(!baseObjectExpr && "anonymous struct/union is static data member?"); - + DeclarationNameInfo baseNameInfo(DeclarationName(), loc); - - ExprResult result + + ExprResult result = BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable); if (result.isInvalid()) return ExprError(); - - baseObjectExpr = result.get(); - baseObjectIsPointer = false; - baseQuals = baseObjectExpr->getType().getQualifiers(); - - // Case 2: the base of the indirect field is a field and the user - // wrote a member expression. - } else if (baseObjectExpr) { - // The caller provided the base object expression. Determine - // whether its a pointer and whether it adds any qualifiers to the - // anonymous struct/union fields we're looking into. - QualType objectType = baseObjectExpr->getType(); - - if (const PointerType *ptr = objectType->getAs<PointerType>()) { - baseObjectIsPointer = true; - objectType = ptr->getPointeeType(); - } else { - baseObjectIsPointer = false; - } - baseQuals = objectType.getQualifiers(); - - // Case 3: the base of the indirect field is a field and we should - // build an implicit member access. - } else { - // We've found a member of an anonymous struct/union that is - // inside a non-anonymous struct/union, so in a well-formed - // program our base object expression is "this". - QualType ThisTy = getCurrentThisType(); - if (ThisTy.isNull()) { - Diag(loc, diag::err_invalid_member_use_in_static_method) - << indirectField->getDeclName(); - return ExprError(); - } - - // Our base object expression is "this". - CheckCXXThisCapture(loc); - baseObjectExpr - = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/ true); - baseObjectIsPointer = true; - baseQuals = ThisTy->castAs<PointerType>()->getPointeeType().getQualifiers(); + + baseObjectExpr = result.get(); } - + + assert((baseVariable || baseObjectExpr) && + "referencing anonymous struct/union without a base variable or " + "expression"); + // Build the implicit member references to the field of the // anonymous struct/union. Expr *result = baseObjectExpr; IndirectFieldDecl::chain_iterator FI = indirectField->chain_begin(), FEnd = indirectField->chain_end(); - - // Build the first member access in the chain with full information. + + // Case 2: the base of the indirect field is a field and the user + // wrote a member expression. if (!baseVariable) { FieldDecl *field = cast<FieldDecl>(*FI); - + + bool baseObjectIsPointer = baseObjectExpr->getType()->isPointerType(); + // Make a nameInfo that properly uses the anonymous name. DeclarationNameInfo memberNameInfo(field->getDeclName(), loc); - result = BuildFieldReferenceExpr(result, baseObjectIsPointer, - SourceLocation(), EmptySS, field, - foundDecl, memberNameInfo).get(); + // Build the first member access in the chain with full information. + result = + BuildFieldReferenceExpr(result, baseObjectIsPointer, SourceLocation(), + SS, field, foundDecl, memberNameInfo) + .get(); if (!result) return ExprError(); - - // FIXME: check qualified member access } - + // In all cases, we should now skip the first declaration in the chain. ++FI; - + while (FI != FEnd) { FieldDecl *field = cast<FieldDecl>(*FI++); @@ -905,7 +873,7 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, fakeFoundDecl, memberNameInfo) .get(); } - + return result; } @@ -922,7 +890,7 @@ BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow, NameInfo.getLoc()); } -/// \brief Build a MemberExpr AST node. +/// Build a MemberExpr AST node. static MemberExpr *BuildMemberExpr( Sema &SemaRef, ASTContext &C, Expr *Base, bool isArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, @@ -937,7 +905,7 @@ static MemberExpr *BuildMemberExpr( return E; } -/// \brief Determine if the given scope is within a function-try-block handler. +/// Determine if the given scope is within a function-try-block handler. static bool IsInFnTryBlockHandler(const Scope *S) { // Walk the scope stack until finding a FnTryCatchScope, or leave the // function scope. If a FnTryCatchScope is found, check whether the TryScope @@ -954,16 +922,12 @@ getVarTemplateSpecialization(Sema &S, VarTemplateDecl *VarTempl, const TemplateArgumentListInfo *TemplateArgs, const DeclarationNameInfo &MemberNameInfo, SourceLocation TemplateKWLoc) { - if (!TemplateArgs) { - S.Diag(MemberNameInfo.getBeginLoc(), diag::err_template_decl_ref) - << /*Variable template*/ 1 << MemberNameInfo.getName() - << MemberNameInfo.getSourceRange(); - - S.Diag(VarTempl->getLocation(), diag::note_template_decl_here); - + S.diagnoseMissingTemplateArguments(TemplateName(VarTempl), + MemberNameInfo.getBeginLoc()); return nullptr; } + DeclResult VDecl = S.CheckVarTemplateId( VarTempl, TemplateKWLoc, MemberNameInfo.getLoc(), *TemplateArgs); if (VDecl.isInvalid()) @@ -1001,8 +965,8 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, return ExprError(); BaseExpr = Converted.get(); } - - + + const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo(); DeclarationName MemberName = MemberNameInfo.getName(); SourceLocation MemberLoc = MemberNameInfo.getLoc(); @@ -1071,7 +1035,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, !SuppressQualifierCheck && CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R)) return ExprError(); - + // Construct an unresolved result if we in fact got an unresolved // result. if (R.isOverloadedResult() || R.isUnresolvableResult()) { @@ -1264,7 +1228,8 @@ Sema::PerformMemberExprBaseConversion(Expr *Base, bool IsArrow) { static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, ExprResult &BaseExpr, bool &IsArrow, SourceLocation OpLoc, CXXScopeSpec &SS, - Decl *ObjCImpDecl, bool HasTemplateArgs) { + Decl *ObjCImpDecl, bool HasTemplateArgs, + SourceLocation TemplateKWLoc) { assert(BaseExpr.get() && "no base expression"); // Perform default conversions. @@ -1314,8 +1279,8 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, // Handle field access to simple records. if (const RecordType *RTy = BaseType->getAs<RecordType>()) { TypoExpr *TE = nullptr; - if (LookupMemberExprInRecord(S, R, BaseExpr.get(), RTy, - OpLoc, IsArrow, SS, HasTemplateArgs, TE)) + if (LookupMemberExprInRecord(S, R, BaseExpr.get(), RTy, OpLoc, IsArrow, SS, + HasTemplateArgs, TemplateKWLoc, TE)) return ExprError(); // Returning valid-but-null is how we indicate to the caller that @@ -1353,7 +1318,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, OpLoc, S.Context.getObjCClassType()); if (ShouldTryAgainWithRedefinitionType(S, BaseExpr)) return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); goto fail; } @@ -1456,7 +1421,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp)) if (UO->getOpcode() == UO_Deref) BaseExp = UO->getSubExpr()->IgnoreParenCasts(); - + if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp)) if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { S.Diag(DE->getLocation(), diag::err_arc_weak_ivar_access); @@ -1466,7 +1431,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, if (warn) { if (ObjCMethodDecl *MD = S.getCurMethodDecl()) { ObjCMethodFamily MF = MD->getMethodFamily(); - warn = (MF != OMF_init && MF != OMF_dealloc && + warn = (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize && !S.IvarBacksCurrentMethodAccessor(IDecl, MD, IV)); } @@ -1479,8 +1444,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, IsArrow); if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { - if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc)) - S.recordUseOfEvaluatedWeak(Result); + if (!S.isUnevaluatedContext() && + !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc)) + S.getCurFunction()->recordUseOfWeak(Result); } return Result; @@ -1524,9 +1490,6 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, } if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) { - // Check the use of this method. - if (S.DiagnoseUseOfDecl(OMD, MemberLoc)) - return ExprError(); Selector SetterSel = SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(), S.PP.getSelectorTable(), @@ -1546,7 +1509,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, // use the 'id' redefinition in this case. if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr)) return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); return ExprError(S.Diag(MemberLoc, diag::err_property_not_found) << MemberName << BaseType); @@ -1559,7 +1522,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, if (!MD) { if (ShouldTryAgainWithRedefinitionType(S, BaseExpr)) return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); goto fail; } @@ -1567,6 +1530,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, // Also must look for a getter name which uses property syntax. Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member); ObjCInterfaceDecl *IFace = MD->getClassInterface(); + if (!IFace) + goto fail; + ObjCMethodDecl *Getter; if ((Getter = IFace->lookupClassMethod(Sel))) { // Check the use of this method. @@ -1598,7 +1564,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, if (ShouldTryAgainWithRedefinitionType(S, BaseExpr)) return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); return ExprError(S.Diag(MemberLoc, diag::err_property_not_found) << MemberName << BaseType); @@ -1623,10 +1589,14 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, else VK = BaseExpr.get()->getValueKind(); } + QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc, Member, MemberLoc); if (ret.isNull()) return ExprError(); + Qualifiers BaseQ = + S.Context.getCanonicalType(BaseExpr.get()->getType()).getQualifiers(); + ret = S.Context.getQualifiedType(ret, BaseQ); return new (S.Context) ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc); @@ -1639,7 +1609,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, BaseExpr = S.ImpCastExprToType( BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast); return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); } // Failure cases. @@ -1662,7 +1632,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, // Recurse as an -> access. IsArrow = true; return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); } } @@ -1676,7 +1646,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, return ExprError(); BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get()); return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, - ObjCImpDecl, HasTemplateArgs); + ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); } S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union) @@ -1762,7 +1732,7 @@ Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, } 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>()) { @@ -1805,7 +1775,7 @@ Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, if (getLangOpts().OpenMP && IsArrow && !CurContext->isDependentContext() && isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) { - if (auto *PrivateCopy = IsOpenMPCapturedDecl(Field)) { + if (auto *PrivateCopy = isOpenMPCapturedDecl(Field)) { return getOpenMPCapturedExpr(PrivateCopy, VK, OK, MemberNameInfo.getLoc()); } @@ -1827,7 +1797,7 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS, const TemplateArgumentListInfo *TemplateArgs, bool IsKnownInstance, const Scope *S) { assert(!R.empty() && !R.isAmbiguous()); - + SourceLocation loc = R.getNameLoc(); // If this is known to be an instance access, go ahead and build an |
