| //===--- SemaExpr.cpp - Semantic Analysis for Expressions -----------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements semantic analysis for expressions. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "TreeTransform.h" |
| #include "clang/AST/ASTConsumer.h" |
| #include "clang/AST/ASTContext.h" |
| #include "clang/AST/ASTLambda.h" |
| #include "clang/AST/ASTMutationListener.h" |
| #include "clang/AST/CXXInheritance.h" |
| #include "clang/AST/DeclObjC.h" |
| #include "clang/AST/DeclTemplate.h" |
| #include "clang/AST/EvaluatedExprVisitor.h" |
| #include "clang/AST/Expr.h" |
| #include "clang/AST/ExprCXX.h" |
| #include "clang/AST/ExprObjC.h" |
| #include "clang/AST/ExprOpenMP.h" |
| #include "clang/AST/RecursiveASTVisitor.h" |
| #include "clang/AST/TypeLoc.h" |
| #include "clang/Basic/PartialDiagnostic.h" |
| #include "clang/Basic/SourceManager.h" |
| #include "clang/Basic/TargetInfo.h" |
| #include "clang/Lex/LiteralSupport.h" |
| #include "clang/Lex/Preprocessor.h" |
| #include "clang/Sema/AnalysisBasedWarnings.h" |
| #include "clang/Sema/DeclSpec.h" |
| #include "clang/Sema/DelayedDiagnostic.h" |
| #include "clang/Sema/Designator.h" |
| #include "clang/Sema/Initialization.h" |
| #include "clang/Sema/Lookup.h" |
| #include "clang/Sema/ParsedTemplate.h" |
| #include "clang/Sema/Scope.h" |
| #include "clang/Sema/ScopeInfo.h" |
| #include "clang/Sema/SemaFixItUtils.h" |
| #include "clang/Sema/SemaInternal.h" |
| #include "clang/Sema/Template.h" |
| #include "llvm/Support/ConvertUTF.h" |
| using namespace clang; |
| using namespace sema; |
| |
| /// \brief Determine whether the use of this declaration is valid, without |
| /// emitting diagnostics. |
| bool Sema::CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid) { |
| // See if this is an auto-typed variable whose initializer we are parsing. |
| if (ParsingInitForAutoVars.count(D)) |
| return false; |
| |
| // See if this is a deleted function. |
| if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { |
| if (FD->isDeleted()) |
| return false; |
| |
| // If the function has a deduced return type, and we can't deduce it, |
| // then we can't use it either. |
| if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && |
| DeduceReturnType(FD, SourceLocation(), /*Diagnose*/ false)) |
| return false; |
| } |
| |
| // See if this function is unavailable. |
| if (TreatUnavailableAsInvalid && D->getAvailability() == AR_Unavailable && |
| cast<Decl>(CurContext)->getAvailability() != AR_Unavailable) |
| return false; |
| |
| return true; |
| } |
| |
| static void DiagnoseUnusedOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc) { |
| // Warn if this is used but marked unused. |
| if (const auto *A = D->getAttr<UnusedAttr>()) { |
| // [[maybe_unused]] should not diagnose uses, but __attribute__((unused)) |
| // should diagnose them. |
| if (A->getSemanticSpelling() != UnusedAttr::CXX11_maybe_unused && |
| A->getSemanticSpelling() != UnusedAttr::C2x_maybe_unused) { |
| const Decl *DC = cast_or_null<Decl>(S.getCurObjCLexicalContext()); |
| if (DC && !DC->hasAttr<UnusedAttr>()) |
| S.Diag(Loc, diag::warn_used_but_marked_unused) << D->getDeclName(); |
| } |
| } |
| } |
| |
| /// \brief Emit a note explaining that this function is deleted. |
| void Sema::NoteDeletedFunction(FunctionDecl *Decl) { |
| assert(Decl->isDeleted()); |
| |
| CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Decl); |
| |
| if (Method && Method->isDeleted() && Method->isDefaulted()) { |
| // If the method was explicitly defaulted, point at that declaration. |
| if (!Method->isImplicit()) |
| Diag(Decl->getLocation(), diag::note_implicitly_deleted); |
| |
| // Try to diagnose why this special member function was implicitly |
| // deleted. This might fail, if that reason no longer applies. |
| CXXSpecialMember CSM = getSpecialMember(Method); |
| if (CSM != CXXInvalid) |
| ShouldDeleteSpecialMember(Method, CSM, nullptr, /*Diagnose=*/true); |
| |
| return; |
| } |
| |
| auto *Ctor = dyn_cast<CXXConstructorDecl>(Decl); |
| if (Ctor && Ctor->isInheritingConstructor()) |
| return NoteDeletedInheritingConstructor(Ctor); |
| |
| Diag(Decl->getLocation(), diag::note_availability_specified_here) |
| << Decl << true; |
| } |
| |
| /// \brief Determine whether a FunctionDecl was ever declared with an |
| /// explicit storage class. |
| static bool hasAnyExplicitStorageClass(const FunctionDecl *D) { |
| for (auto I : D->redecls()) { |
| if (I->getStorageClass() != SC_None) |
| return true; |
| } |
| return false; |
| } |
| |
| /// \brief Check whether we're in an extern inline function and referring to a |
| /// variable or function with internal linkage (C11 6.7.4p3). |
| /// |
| /// This is only a warning because we used to silently accept this code, but |
| /// in many cases it will not behave correctly. This is not enabled in C++ mode |
| /// because the restriction language is a bit weaker (C++11 [basic.def.odr]p6) |
| /// and so while there may still be user mistakes, most of the time we can't |
| /// prove that there are errors. |
| static void diagnoseUseOfInternalDeclInInlineFunction(Sema &S, |
| const NamedDecl *D, |
| SourceLocation Loc) { |
| // This is disabled under C++; there are too many ways for this to fire in |
| // contexts where the warning is a false positive, or where it is technically |
| // correct but benign. |
| if (S.getLangOpts().CPlusPlus) |
| return; |
| |
| // Check if this is an inlined function or method. |
| FunctionDecl *Current = S.getCurFunctionDecl(); |
| if (!Current) |
| return; |
| if (!Current->isInlined()) |
| return; |
| if (!Current->isExternallyVisible()) |
| return; |
| |
| // Check if the decl has internal linkage. |
| if (D->getFormalLinkage() != InternalLinkage) |
| return; |
| |
| // Downgrade from ExtWarn to Extension if |
| // (1) the supposedly external inline function is in the main file, |
| // and probably won't be included anywhere else. |
| // (2) the thing we're referencing is a pure function. |
| // (3) the thing we're referencing is another inline function. |
| // This last can give us false negatives, but it's better than warning on |
| // wrappers for simple C library functions. |
| const FunctionDecl *UsedFn = dyn_cast<FunctionDecl>(D); |
| bool DowngradeWarning = S.getSourceManager().isInMainFile(Loc); |
| if (!DowngradeWarning && UsedFn) |
| DowngradeWarning = UsedFn->isInlined() || UsedFn->hasAttr<ConstAttr>(); |
| |
| S.Diag(Loc, DowngradeWarning ? diag::ext_internal_in_extern_inline_quiet |
| : diag::ext_internal_in_extern_inline) |
| << /*IsVar=*/!UsedFn << D; |
| |
| S.MaybeSuggestAddingStaticToDecl(Current); |
| |
| S.Diag(D->getCanonicalDecl()->getLocation(), diag::note_entity_declared_at) |
| << D; |
| } |
| |
| void Sema::MaybeSuggestAddingStaticToDecl(const FunctionDecl *Cur) { |
| const FunctionDecl *First = Cur->getFirstDecl(); |
| |
| // Suggest "static" on the function, if possible. |
| if (!hasAnyExplicitStorageClass(First)) { |
| SourceLocation DeclBegin = First->getSourceRange().getBegin(); |
| Diag(DeclBegin, diag::note_convert_inline_to_static) |
| << Cur << FixItHint::CreateInsertion(DeclBegin, "static "); |
| } |
| } |
| |
| /// \brief Determine whether the use of this declaration is valid, and |
| /// emit any corresponding diagnostics. |
| /// |
| /// This routine diagnoses various problems with referencing |
| /// declarations that can occur when using a declaration. For example, |
| /// it might warn if a deprecated or unavailable declaration is being |
| /// used, or produce an error (and return true) if a C++0x deleted |
| /// function is being used. |
| /// |
| /// \returns true if there was an error (this declaration cannot be |
| /// referenced), false otherwise. |
| /// |
| bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, |
| const ObjCInterfaceDecl *UnknownObjCClass, |
| bool ObjCPropertyAccess, |
| bool AvoidPartialAvailabilityChecks) { |
| if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) { |
| // If there were any diagnostics suppressed by template argument deduction, |
| // emit them now. |
| auto Pos = SuppressedDiagnostics.find(D->getCanonicalDecl()); |
| if (Pos != SuppressedDiagnostics.end()) { |
| for (const PartialDiagnosticAt &Suppressed : Pos->second) |
| Diag(Suppressed.first, Suppressed.second); |
| |
| // Clear out the list of suppressed diagnostics, so that we don't emit |
| // them again for this specialization. However, we don't obsolete this |
| // entry from the table, because we want to avoid ever emitting these |
| // diagnostics again. |
| Pos->second.clear(); |
| } |
| |
| // C++ [basic.start.main]p3: |
| // The function 'main' shall not be used within a program. |
| if (cast<FunctionDecl>(D)->isMain()) |
| Diag(Loc, diag::ext_main_used); |
| } |
| |
| // See if this is an auto-typed variable whose initializer we are parsing. |
| if (ParsingInitForAutoVars.count(D)) { |
| if (isa<BindingDecl>(D)) { |
| Diag(Loc, diag::err_binding_cannot_appear_in_own_initializer) |
| << D->getDeclName(); |
| } else { |
| Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer) |
| << D->getDeclName() << cast<VarDecl>(D)->getType(); |
| } |
| return true; |
| } |
| |
| // See if this is a deleted function. |
| if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { |
| if (FD->isDeleted()) { |
| auto *Ctor = dyn_cast<CXXConstructorDecl>(FD); |
| if (Ctor && Ctor->isInheritingConstructor()) |
| Diag(Loc, diag::err_deleted_inherited_ctor_use) |
| << Ctor->getParent() |
| << Ctor->getInheritedConstructor().getConstructor()->getParent(); |
| else |
| Diag(Loc, diag::err_deleted_function_use); |
| NoteDeletedFunction(FD); |
| return true; |
| } |
| |
| // If the function has a deduced return type, and we can't deduce it, |
| // then we can't use it either. |
| if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && |
| DeduceReturnType(FD, Loc)) |
| return true; |
| |
| if (getLangOpts().CUDA && !CheckCUDACall(Loc, FD)) |
| return true; |
| } |
| |
| auto getReferencedObjCProp = [](const NamedDecl *D) -> |
| const ObjCPropertyDecl * { |
| if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) |
| return MD->findPropertyDecl(); |
| return nullptr; |
| }; |
| if (const ObjCPropertyDecl *ObjCPDecl = getReferencedObjCProp(D)) { |
| if (diagnoseArgIndependentDiagnoseIfAttrs(ObjCPDecl, Loc)) |
| return true; |
| } else if (diagnoseArgIndependentDiagnoseIfAttrs(D, Loc)) { |
| return true; |
| } |
| |
| // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions |
| // Only the variables omp_in and omp_out are allowed in the combiner. |
| // Only the variables omp_priv and omp_orig are allowed in the |
| // initializer-clause. |
| auto *DRD = dyn_cast<OMPDeclareReductionDecl>(CurContext); |
| if (LangOpts.OpenMP && DRD && !CurContext->containsDecl(D) && |
| isa<VarDecl>(D)) { |
| Diag(Loc, diag::err_omp_wrong_var_in_declare_reduction) |
| << getCurFunction()->HasOMPDeclareReductionCombiner; |
| Diag(D->getLocation(), diag::note_entity_declared_at) << D; |
| return true; |
| } |
| |
| DiagnoseAvailabilityOfDecl(D, Loc, UnknownObjCClass, ObjCPropertyAccess, |
| AvoidPartialAvailabilityChecks); |
| |
| DiagnoseUnusedOfDecl(*this, D, Loc); |
| |
| diagnoseUseOfInternalDeclInInlineFunction(*this, D, Loc); |
| |
| return false; |
| } |
| |
| /// \brief Retrieve the message suffix that should be added to a |
| /// diagnostic complaining about the given function being deleted or |
| /// unavailable. |
| std::string Sema::getDeletedOrUnavailableSuffix(const FunctionDecl *FD) { |
| std::string Message; |
| if (FD->getAvailability(&Message)) |
| return ": " + Message; |
| |
| return std::string(); |
| } |
| |
| /// DiagnoseSentinelCalls - This routine checks whether a call or |
| /// message-send is to a declaration with the sentinel attribute, and |
| /// if so, it checks that the requirements of the sentinel are |
| /// satisfied. |
| void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, |
| ArrayRef<Expr *> Args) { |
| const SentinelAttr *attr = D->getAttr<SentinelAttr>(); |
| if (!attr) |
| return; |
| |
| // The number of formal parameters of the declaration. |
| unsigned numFormalParams; |
| |
| // The kind of declaration. This is also an index into a %select in |
| // the diagnostic. |
| enum CalleeType { CT_Function, CT_Method, CT_Block } calleeType; |
| |
| if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { |
| numFormalParams = MD->param_size(); |
| calleeType = CT_Method; |
| } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { |
| numFormalParams = FD->param_size(); |
| calleeType = CT_Function; |
| } else if (isa<VarDecl>(D)) { |
| QualType type = cast<ValueDecl>(D)->getType(); |
| const FunctionType *fn = nullptr; |
| if (const PointerType *ptr = type->getAs<PointerType>()) { |
| fn = ptr->getPointeeType()->getAs<FunctionType>(); |
| if (!fn) return; |
| calleeType = CT_Function; |
| } else if (const BlockPointerType *ptr = type->getAs<BlockPointerType>()) { |
| fn = ptr->getPointeeType()->castAs<FunctionType>(); |
| calleeType = CT_Block; |
| } else { |
| return; |
| } |
| |
| if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fn)) { |
| numFormalParams = proto->getNumParams(); |
| } else { |
| numFormalParams = 0; |
| } |
| } else { |
| return; |
| } |
| |
| // "nullPos" is the number of formal parameters at the end which |
| // effectively count as part of the variadic arguments. This is |
| // useful if you would prefer to not have *any* formal parameters, |
| // but the language forces you to have at least one. |
| unsigned nullPos = attr->getNullPos(); |
| assert((nullPos == 0 || nullPos == 1) && "invalid null position on sentinel"); |
| numFormalParams = (nullPos > numFormalParams ? 0 : numFormalParams - nullPos); |
| |
| // The number of arguments which should follow the sentinel. |
| unsigned numArgsAfterSentinel = attr->getSentinel(); |
| |
| // If there aren't enough arguments for all the formal parameters, |
| // the sentinel, and the args after the sentinel, complain. |
| if (Args.size() < numFormalParams + numArgsAfterSentinel + 1) { |
| Diag(Loc, diag::warn_not_enough_argument) << D->getDeclName(); |
| Diag(D->getLocation(), diag::note_sentinel_here) << int(calleeType); |
| return; |
| } |
| |
| // Otherwise, find the sentinel expression. |
| Expr *sentinelExpr = Args[Args.size() - numArgsAfterSentinel - 1]; |
| if (!sentinelExpr) return; |
| if (sentinelExpr->isValueDependent()) return; |
| if (Context.isSentinelNullExpr(sentinelExpr)) return; |
| |
| // Pick a reasonable string to insert. Optimistically use 'nil', 'nullptr', |
| // or 'NULL' if those are actually defined in the context. Only use |
| // 'nil' for ObjC methods, where it's much more likely that the |
| // variadic arguments form a list of object pointers. |
| SourceLocation MissingNilLoc |
| = getLocForEndOfToken(sentinelExpr->getLocEnd()); |
| std::string NullValue; |
| if (calleeType == CT_Method && PP.isMacroDefined("nil")) |
| NullValue = "nil"; |
| else if (getLangOpts().CPlusPlus11) |
| NullValue = "nullptr"; |
| else if (PP.isMacroDefined("NULL")) |
| NullValue = "NULL"; |
| else |
| NullValue = "(void*) 0"; |
| |
| if (MissingNilLoc.isInvalid()) |
| Diag(Loc, diag::warn_missing_sentinel) << int(calleeType); |
| else |
| Diag(MissingNilLoc, diag::warn_missing_sentinel) |
| << int(calleeType) |
| << FixItHint::CreateInsertion(MissingNilLoc, ", " + NullValue); |
| Diag(D->getLocation(), diag::note_sentinel_here) << int(calleeType); |
| } |
| |
| SourceRange Sema::getExprRange(Expr *E) const { |
| return E ? E->getSourceRange() : SourceRange(); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Standard Promotions and Conversions |
| //===----------------------------------------------------------------------===// |
| |
| /// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4). |
| ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) { |
| // Handle any placeholder expressions which made it here. |
| if (E->getType()->isPlaceholderType()) { |
| ExprResult result = CheckPlaceholderExpr(E); |
| if (result.isInvalid()) return ExprError(); |
| E = result.get(); |
| } |
| |
| QualType Ty = E->getType(); |
| assert(!Ty.isNull() && "DefaultFunctionArrayConversion - missing type"); |
| |
| if (Ty->isFunctionType()) { |
| if (auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts())) |
| if (auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) |
| if (!checkAddressOfFunctionIsAvailable(FD, Diagnose, E->getExprLoc())) |
| return ExprError(); |
| |
| E = ImpCastExprToType(E, Context.getPointerType(Ty), |
| CK_FunctionToPointerDecay).get(); |
| } else if (Ty->isArrayType()) { |
| // In C90 mode, arrays only promote to pointers if the array expression is |
| // an lvalue. The relevant legalese is C90 6.2.2.1p3: "an lvalue that has |
| // type 'array of type' is converted to an expression that has type 'pointer |
| // to type'...". In C99 this was changed to: C99 6.3.2.1p3: "an expression |
| // that has type 'array of type' ...". The relevant change is "an lvalue" |
| // (C90) to "an expression" (C99). |
| // |
| // C++ 4.2p1: |
| // An lvalue or rvalue of type "array of N T" or "array of unknown bound of |
| // T" can be converted to an rvalue of type "pointer to T". |
| // |
| if (getLangOpts().C99 || getLangOpts().CPlusPlus || E->isLValue()) |
| E = ImpCastExprToType(E, Context.getArrayDecayedType(Ty), |
| CK_ArrayToPointerDecay).get(); |
| } |
| return E; |
| } |
| |
| static void CheckForNullPointerDereference(Sema &S, Expr *E) { |
| // Check to see if we are dereferencing a null pointer. If so, |
| // and if not volatile-qualified, this is undefined behavior that the |
| // optimizer will delete, so warn about it. People sometimes try to use this |
| // to get a deterministic trap and are surprised by clang's behavior. This |
| // only handles the pattern "*null", which is a very syntactic check. |
| if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts())) |
| if (UO->getOpcode() == UO_Deref && |
| UO->getSubExpr()->IgnoreParenCasts()-> |
| isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull) && |
| !UO->getType().isVolatileQualified()) { |
| S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO, |
| S.PDiag(diag::warn_indirection_through_null) |
| << UO->getSubExpr()->getSourceRange()); |
| S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO, |
| S.PDiag(diag::note_indirection_through_null)); |
| } |
| } |
| |
| static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE, |
| SourceLocation AssignLoc, |
| const Expr* RHS) { |
| const ObjCIvarDecl *IV = OIRE->getDecl(); |
| if (!IV) |
| return; |
| |
| DeclarationName MemberName = IV->getDeclName(); |
| IdentifierInfo *Member = MemberName.getAsIdentifierInfo(); |
| if (!Member || !Member->isStr("isa")) |
| return; |
| |
| const Expr *Base = OIRE->getBase(); |
| QualType BaseType = Base->getType(); |
| if (OIRE->isArrow()) |
| BaseType = BaseType->getPointeeType(); |
| if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) |
| if (ObjCInterfaceDecl *IDecl = OTy->getInterface()) { |
| ObjCInterfaceDecl *ClassDeclared = nullptr; |
| ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared); |
| if (!ClassDeclared->getSuperClass() |
| && (*ClassDeclared->ivar_begin()) == IV) { |
| if (RHS) { |
| NamedDecl *ObjectSetClass = |
| S.LookupSingleName(S.TUScope, |
| &S.Context.Idents.get("object_setClass"), |
| SourceLocation(), S.LookupOrdinaryName); |
| if (ObjectSetClass) { |
| SourceLocation RHSLocEnd = S.getLocForEndOfToken(RHS->getLocEnd()); |
| S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_assign) << |
| FixItHint::CreateInsertion(OIRE->getLocStart(), "object_setClass(") << |
| FixItHint::CreateReplacement(SourceRange(OIRE->getOpLoc(), |
| AssignLoc), ",") << |
| FixItHint::CreateInsertion(RHSLocEnd, ")"); |
| } |
| else |
| S.Diag(OIRE->getLocation(), diag::warn_objc_isa_assign); |
| } else { |
| NamedDecl *ObjectGetClass = |
| S.LookupSingleName(S.TUScope, |
| &S.Context.Idents.get("object_getClass"), |
| SourceLocation(), S.LookupOrdinaryName); |
| if (ObjectGetClass) |
| S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_use) << |
| FixItHint::CreateInsertion(OIRE->getLocStart(), "object_getClass(") << |
| FixItHint::CreateReplacement( |
| SourceRange(OIRE->getOpLoc(), |
| OIRE->getLocEnd()), ")"); |
| else |
| S.Diag(OIRE->getLocation(), diag::warn_objc_isa_use); |
| } |
| S.Diag(IV->getLocation(), diag::note_ivar_decl); |
| } |
| } |
| } |
| |
| ExprResult Sema::DefaultLvalueConversion(Expr *E) { |
| // Handle any placeholder expressions which made it here. |
| if (E->getType()->isPlaceholderType()) { |
| ExprResult result = CheckPlaceholderExpr(E); |
| if (result.isInvalid()) return ExprError(); |
| E = result.get(); |
| } |
| |
| // C++ [conv.lval]p1: |
| // A glvalue of a non-function, non-array type T can be |
| // converted to a prvalue. |
| if (!E->isGLValue()) return E; |
| |
| QualType T = E->getType(); |
| assert(!T.isNull() && "r-value conversion on typeless expression?"); |
| |
| // We don't want to throw lvalue-to-rvalue casts on top of |
| // expressions of certain types in C++. |
| if (getLangOpts().CPlusPlus && |
| (E->getType() == Context.OverloadTy || |
| T->isDependentType() || |
| T->isRecordType())) |
| return E; |
| |
| // The C standard is actually really unclear on this point, and |
| // DR106 tells us what the result should be but not why. It's |
| // generally best to say that void types just doesn't undergo |
| // lvalue-to-rvalue at all. Note that expressions of unqualified |
| // 'void' type are never l-values, but qualified void can be. |
| if (T->isVoidType()) |
| return E; |
| |
| // OpenCL usually rejects direct accesses to values of 'half' type. |
| if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp16") && |
| T->isHalfType()) { |
| Diag(E->getExprLoc(), diag::err_opencl_half_load_store) |
| << 0 << T; |
| return ExprError(); |
| } |
| |
| CheckForNullPointerDereference(*this, E); |
| if (const ObjCIsaExpr *OISA = dyn_cast<ObjCIsaExpr>(E->IgnoreParenCasts())) { |
| NamedDecl *ObjectGetClass = LookupSingleName(TUScope, |
| &Context.Idents.get("object_getClass"), |
| SourceLocation(), LookupOrdinaryName); |
| if (ObjectGetClass) |
| Diag(E->getExprLoc(), diag::warn_objc_isa_use) << |
| FixItHint::CreateInsertion(OISA->getLocStart(), "object_getClass(") << |
| FixItHint::CreateReplacement( |
| SourceRange(OISA->getOpLoc(), OISA->getIsaMemberLoc()), ")"); |
| else |
| Diag(E->getExprLoc(), diag::warn_objc_isa_use); |
| } |
| else if (const ObjCIvarRefExpr *OIRE = |
| dyn_cast<ObjCIvarRefExpr>(E->IgnoreParenCasts())) |
| DiagnoseDirectIsaAccess(*this, OIRE, SourceLocation(), /* Expr*/nullptr); |
| |
| // C++ [conv.lval]p1: |
| // [...] If T is a non-class type, the type of the prvalue is the |
| // cv-unqualified version of T. Otherwise, the type of the |
| // rvalue is T. |
| // |
| // C99 6.3.2.1p2: |
| // If the lvalue has qualified type, the value has the unqualified |
| // version of the type of the lvalue; otherwise, the value has the |
| // type of the lvalue. |
| if (T.hasQualifiers()) |
| T = T.getUnqualifiedType(); |
| |
| // Under the MS ABI, lock down the inheritance model now. |
| if (T->isMemberPointerType() && |
| Context.getTargetInfo().getCXXABI().isMicrosoft()) |
| (void)isCompleteType(E->getExprLoc(), T); |
| |
| UpdateMarkingForLValueToRValue(E); |
| |
| // Loading a __weak object implicitly retains the value, so we need a cleanup to |
| // balance that. |
| if (E->getType().getObjCLifetime() == Qualifiers::OCL_Weak) |
| Cleanup.setExprNeedsCleanups(true); |
| |
| ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E, |
| nullptr, VK_RValue); |
| |
| // C11 6.3.2.1p2: |
| // ... if the lvalue has atomic type, the value has the non-atomic version |
| // of the type of the lvalue ... |
| if (const AtomicType *Atomic = T->getAs<AtomicType>()) { |
| T = Atomic->getValueType().getUnqualifiedType(); |
| Res = ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic, Res.get(), |
| nullptr, VK_RValue); |
| } |
| |
| return Res; |
| } |
| |
| ExprResult Sema::DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose) { |
| ExprResult Res = DefaultFunctionArrayConversion(E, Diagnose); |
| if (Res.isInvalid()) |
| return ExprError(); |
| Res = DefaultLvalueConversion(Res.get()); |
| if (Res.isInvalid()) |
| return ExprError(); |
| return Res; |
| } |
| |
| /// CallExprUnaryConversions - a special case of an unary conversion |
| /// performed on a function designator of a call expression. |
| ExprResult Sema::CallExprUnaryConversions(Expr *E) { |
| QualType Ty = E->getType(); |
| ExprResult Res = E; |
| // Only do implicit cast for a function type, but not for a pointer |
| // to function type. |
| if (Ty->isFunctionType()) { |
| Res = ImpCastExprToType(E, Context.getPointerType(Ty), |
| CK_FunctionToPointerDecay).get(); |
| if (Res.isInvalid()) |
| return ExprError(); |
| } |
| Res = DefaultLvalueConversion(Res.get()); |
| if (Res.isInvalid()) |
| return ExprError(); |
| return Res.get(); |
| } |
| |
| /// UsualUnaryConversions - Performs various conversions that are common to most |
| /// operators (C99 6.3). The conversions of array and function types are |
| /// sometimes suppressed. For example, the array->pointer conversion doesn't |
| /// apply if the array is an argument to the sizeof or address (&) operators. |
| /// In these instances, this routine should *not* be called. |
| ExprResult Sema::UsualUnaryConversions(Expr *E) { |
| // First, convert to an r-value. |
| ExprResult Res = DefaultFunctionArrayLvalueConversion(E); |
| if (Res.isInvalid()) |
| return ExprError(); |
| E = Res.get(); |
| |
| QualType Ty = E->getType(); |
| assert(!Ty.isNull() && "UsualUnaryConversions - missing type"); |
| |
| // Half FP have to be promoted to float unless it is natively supported |
| if (Ty->isHalfType() && !getLangOpts().NativeHalfType) |
| return ImpCastExprToType(Res.get(), Context.FloatTy, CK_FloatingCast); |
| |
| // Try to perform integral promotions if the object has a theoretically |
| // promotable type. |
| if (Ty->isIntegralOrUnscopedEnumerationType()) { |
| // C99 6.3.1.1p2: |
| // |
| // The following may be used in an expression wherever an int or |
| // unsigned int may be used: |
| // - an object or expression with an integer type whose integer |
| // conversion rank is less than or equal to the rank of int |
| // and unsigned int. |
| // - A bit-field of type _Bool, int, signed int, or unsigned int. |
| // |
| // If an int can represent all values of the original type, the |
| // value is converted to an int; otherwise, it is converted to an |
| // unsigned int. These are called the integer promotions. All |
| // other types are unchanged by the integer promotions. |
| |
| QualType PTy = Context.isPromotableBitField(E); |
| if (!PTy.isNull()) { |
| E = ImpCastExprToType(E, PTy, CK_IntegralCast).get(); |
| return E; |
| } |
| if (Ty->isPromotableIntegerType()) { |
| QualType PT = Context.getPromotedIntegerType(Ty); |
| E = ImpCastExprToType(E, PT, CK_IntegralCast).get(); |
| return E; |
| } |
| } |
| return E; |
| } |
| |
| /// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that |
| /// do not have a prototype. Arguments that have type float or __fp16 |
| /// are promoted to double. All other argument types are converted by |
| /// UsualUnaryConversions(). |
| ExprResult Sema::DefaultArgumentPromotion(Expr *E) { |
| QualType Ty = E->getType(); |
| assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type"); |
| |
| ExprResult Res = UsualUnaryConversions(E); |
| if (Res.isInvalid()) |
| return ExprError(); |
| E = Res.get(); |
| |
| // If this is a 'float' or '__fp16' (CVR qualified or typedef) |
| // promote to double. |
| // Note that default argument promotion applies only to float (and |
| // half/fp16); it does not apply to _Float16. |
| const BuiltinType *BTy = Ty->getAs<BuiltinType>(); |
| if (BTy && (BTy->getKind() == BuiltinType::Half || |
| BTy->getKind() == BuiltinType::Float)) { |
| if (getLangOpts().OpenCL && |
| !getOpenCLOptions().isEnabled("cl_khr_fp64")) { |
| if (BTy->getKind() == BuiltinType::Half) { |
| E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); |
| } |
| } else { |
| E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get(); |
| } |
| } |
| |
| // C++ performs lvalue-to-rvalue conversion as a default argument |
| // promotion, even on class types, but note: |
| // C++11 [conv.lval]p2: |
| // When an lvalue-to-rvalue conversion occurs in an unevaluated |
| // operand or a subexpression thereof the value contained in the |
| // referenced object is not accessed. Otherwise, if the glvalue |
| // has a class type, the conversion copy-initializes a temporary |
| // of type T from the glvalue and the result of the conversion |
| // is a prvalue for the temporary. |
| // FIXME: add some way to gate this entire thing for correctness in |
| // potentially potentially evaluated contexts. |
| if (getLangOpts().CPlusPlus && E->isGLValue() && !isUnevaluatedContext()) { |
| ExprResult Temp = PerformCopyInitialization( |
| InitializedEntity::InitializeTemporary(E->getType()), |
| E->getExprLoc(), E); |
| if (Temp.isInvalid()) |
| return ExprError(); |
| E = Temp.get(); |
| } |
| |
| return E; |
| } |
| |
| /// Determine the degree of POD-ness for an expression. |
| /// Incomplete types are considered POD, since this check can be performed |
| /// when we're in an unevaluated context. |
| Sema::VarArgKind Sema::isValidVarArgType(const QualType &Ty) { |
| if (Ty->isIncompleteType()) { |
| // C++11 [expr.call]p7: |
| // After these conversions, if the argument does not have arithmetic, |
| // enumeration, pointer, pointer to member, or class type, the program |
| // is ill-formed. |
| // |
| // Since we've already performed array-to-pointer and function-to-pointer |
| // decay, the only such type in C++ is cv void. This also handles |
| // initializer lists as variadic arguments. |
| if (Ty->isVoidType()) |
| return VAK_Invalid; |
| |
| if (Ty->isObjCObjectType()) |
| return VAK_Invalid; |
| return VAK_Valid; |
| } |
| |
| if (Ty.isCXX98PODType(Context)) |
| return VAK_Valid; |
| |
| // C++11 [expr.call]p7: |
| // Passing a potentially-evaluated argument of class type (Clause 9) |
| // having a non-trivial copy constructor, a non-trivial move constructor, |
| // or a non-trivial destructor, with no corresponding parameter, |
| // is conditionally-supported with implementation-defined semantics. |
| if (getLangOpts().CPlusPlus11 && !Ty->isDependentType()) |
| if (CXXRecordDecl *Record = Ty->getAsCXXRecordDecl()) |
| if (!Record->hasNonTrivialCopyConstructor() && |
| !Record->hasNonTrivialMoveConstructor() && |
| !Record->hasNonTrivialDestructor()) |
| return VAK_ValidInCXX11; |
| |
| if (getLangOpts().ObjCAutoRefCount && Ty->isObjCLifetimeType()) |
| return VAK_Valid; |
| |
| if (Ty->isObjCObjectType()) |
| return VAK_Invalid; |
| |
| if (getLangOpts().MSVCCompat) |
| return VAK_MSVCUndefined; |
| |
| // FIXME: In C++11, these cases are conditionally-supported, meaning we're |
| // permitted to reject them. We should consider doing so. |
| return VAK_Undefined; |
| } |
| |
| void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) { |
| // Don't allow one to pass an Objective-C interface to a vararg. |
| const QualType &Ty = E->getType(); |
| VarArgKind VAK = isValidVarArgType(Ty); |
| |
| // Complain about passing non-POD types through varargs. |
| switch (VAK) { |
| case VAK_ValidInCXX11: |
| DiagRuntimeBehavior( |
| E->getLocStart(), nullptr, |
| PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg) |
| << Ty << CT); |
| LLVM_FALLTHROUGH; |
| case VAK_Valid: |
| if (Ty->isRecordType()) { |
| // This is unlikely to be what the user intended. If the class has a |
| // 'c_str' member function, the user probably meant to call that. |
| DiagRuntimeBehavior(E->getLocStart(), nullptr, |
| PDiag(diag::warn_pass_class_arg_to_vararg) |
| << Ty << CT << hasCStrMethod(E) << ".c_str()"); |
| } |
| break; |
| |
| case VAK_Undefined: |
| case VAK_MSVCUndefined: |
| DiagRuntimeBehavior( |
| E->getLocStart(), nullptr, |
| PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) |
| << getLangOpts().CPlusPlus11 << Ty << CT); |
| break; |
| |
| case VAK_Invalid: |
| if (Ty->isObjCObjectType()) |
| DiagRuntimeBehavior( |
| E->getLocStart(), nullptr, |
| PDiag(diag::err_cannot_pass_objc_interface_to_vararg) |
| << Ty << CT); |
| else |
| Diag(E->getLocStart(), diag::err_cannot_pass_to_vararg) |
| << isa<InitListExpr>(E) << Ty << CT; |
| break; |
| } |
| } |
| |
| /// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but |
| /// will create a trap if the resulting type is not a POD type. |
| ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, |
| FunctionDecl *FDecl) { |
| if (const BuiltinType *PlaceholderTy = E->getType()->getAsPlaceholderType()) { |
| // Strip the unbridged-cast placeholder expression off, if applicable. |
| if (PlaceholderTy->getKind() == BuiltinType::ARCUnbridgedCast && |
| (CT == VariadicMethod || |
| (FDecl && FDecl->hasAttr<CFAuditedTransferAttr>()))) { |
| E = stripARCUnbridgedCast(E); |
| |
| // Otherwise, do normal placeholder checking. |
| } else { |
| ExprResult ExprRes = CheckPlaceholderExpr(E); |
| if (ExprRes.isInvalid()) |
| return ExprError(); |
| E = ExprRes.get(); |
| } |
| } |
| |
| ExprResult ExprRes = DefaultArgumentPromotion(E); |
| if (ExprRes.isInvalid()) |
| return ExprError(); |
| E = ExprRes.get(); |
| |
| // Diagnostics regarding non-POD argument types are |
| // emitted along with format string checking in Sema::CheckFunctionCall(). |
| if (isValidVarArgType(E->getType()) == VAK_Undefined) { |
| // Turn this into a trap. |
| CXXScopeSpec SS; |
| SourceLocation TemplateKWLoc; |
| UnqualifiedId Name; |
| Name.setIdentifier(PP.getIdentifierInfo("__builtin_trap"), |
| E->getLocStart()); |
| ExprResult TrapFn = ActOnIdExpression(TUScope, SS, TemplateKWLoc, |
| Name, true, false); |
| if (TrapFn.isInvalid()) |
| return ExprError(); |
| |
| ExprResult Call = ActOnCallExpr(TUScope, TrapFn.get(), |
| E->getLocStart(), None, |
| E->getLocEnd()); |
| if (Call.isInvalid()) |
| return ExprError(); |
| |
| ExprResult Comma = ActOnBinOp(TUScope, E->getLocStart(), tok::comma, |
| Call.get(), E); |
| if (Comma.isInvalid()) |
| return ExprError(); |
| return Comma.get(); |
| } |
| |
| if (!getLangOpts().CPlusPlus && |
| RequireCompleteType(E->getExprLoc(), E->getType(), |
| diag::err_call_incomplete_argument)) |
| return ExprError(); |
| |
| return E; |
| } |
| |
| /// \brief Converts an integer to complex float type. Helper function of |
| /// UsualArithmeticConversions() |
| /// |
| /// \return false if the integer expression is an integer type and is |
| /// successfully converted to the complex type. |
| static bool handleIntegerToComplexFloatConversion(Sema &S, ExprResult &IntExpr, |
| ExprResult &ComplexExpr, |
| QualType IntTy, |
| QualType ComplexTy, |
| bool SkipCast) { |
| if (IntTy->isComplexType() || IntTy->isRealFloatingType()) return true; |
| if (SkipCast) return false; |
| if (IntTy->isIntegerType()) { |
| QualType fpTy = cast<ComplexType>(ComplexTy)->getElementType(); |
| IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating); |
| IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy, |
| CK_FloatingRealToComplex); |
| } else { |
| assert(IntTy->isComplexIntegerType()); |
| IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy, |
| CK_IntegralComplexToFloatingComplex); |
| } |
| return false; |
| } |
| |
| /// \brief Handle arithmetic conversion with complex types. Helper function of |
| /// UsualArithmeticConversions() |
| static QualType handleComplexFloatConversion(Sema &S, ExprResult &LHS, |
| ExprResult &RHS, QualType LHSType, |
| QualType RHSType, |
| bool IsCompAssign) { |
| // if we have an integer operand, the result is the complex type. |
| if (!handleIntegerToComplexFloatConversion(S, RHS, LHS, RHSType, LHSType, |
| /*skipCast*/false)) |
| return LHSType; |
| if (!handleIntegerToComplexFloatConversion(S, LHS, RHS, LHSType, RHSType, |
| /*skipCast*/IsCompAssign)) |
| return RHSType; |
| |
| // This handles complex/complex, complex/float, or float/complex. |
| // When both operands are complex, the shorter operand is converted to the |
| // type of the longer, and that is the type of the result. This corresponds |
| // to what is done when combining two real floating-point operands. |
| // The fun begins when size promotion occur across type domains. |
| // From H&S 6.3.4: When one operand is complex and the other is a real |
| // floating-point type, the less precise type is converted, within it's |
| // real or complex domain, to the precision of the other type. For example, |
| // when combining a "long double" with a "double _Complex", the |
| // "double _Complex" is promoted to "long double _Complex". |
| |
| // Compute the rank of the two types, regardless of whether they are complex. |
| int Order = S.Context.getFloatingTypeOrder(LHSType, RHSType); |
| |
| auto *LHSComplexType = dyn_cast<ComplexType>(LHSType); |
| auto *RHSComplexType = dyn_cast<ComplexType>(RHSType); |
| QualType LHSElementType = |
| LHSComplexType ? LHSComplexType->getElementType() : LHSType; |
| QualType RHSElementType = |
| RHSComplexType ? RHSComplexType->getElementType() : RHSType; |
| |
| QualType ResultType = S.Context.getComplexType(LHSElementType); |
| if (Order < 0) { |
| // Promote the precision of the LHS if not an assignment. |
| ResultType = S.Context.getComplexType(RHSElementType); |
| if (!IsCompAssign) { |
| if (LHSComplexType) |
| LHS = |
| S.ImpCastExprToType(LHS.get(), ResultType, CK_FloatingComplexCast); |
| else |
| LHS = S.ImpCastExprToType(LHS.get(), RHSElementType, CK_FloatingCast); |
| } |
| } else if (Order > 0) { |
| // Promote the precision of the RHS. |
| if (RHSComplexType) |
| RHS = S.ImpCastExprToType(RHS.get(), ResultType, CK_FloatingComplexCast); |
| else |
| RHS = S.ImpCastExprToType(RHS.get(), LHSElementType, CK_FloatingCast); |
| } |
| return ResultType; |
| } |
| |
| /// \brief Handle arithmetic conversion from integer to float. Helper function |
| /// of UsualArithmeticConversions() |
| static QualType handleIntToFloatConversion(Sema &S, ExprResult &FloatExpr, |
| ExprResult &IntExpr, |
| QualType FloatTy, QualType IntTy, |
| bool ConvertFloat, bool ConvertInt) { |
| if (IntTy->isIntegerType()) { |
| if (ConvertInt) |
| // Convert intExpr to the lhs floating point type. |
| IntExpr = S.ImpCastExprToType(IntExpr.get(), FloatTy, |
| CK_IntegralToFloating); |
| return FloatTy; |
| } |
| |
| // Convert both sides to the appropriate complex float. |
| assert(IntTy->isComplexIntegerType()); |
| QualType result = S.Context.getComplexType(FloatTy); |
| |
| // _Complex int -> _Complex float |
| if (ConvertInt) |
| IntExpr = S.ImpCastExprToType(IntExpr.get(), result, |
| CK_IntegralComplexToFloatingComplex); |
| |
| // float -> _Complex float |
| if (ConvertFloat) |
| FloatExpr = S.ImpCastExprToType(FloatExpr.get(), result, |
| CK_FloatingRealToComplex); |
| |
| return result; |
| } |
| |
| /// \brief Handle arithmethic conversion with floating point types. Helper |
| /// function of UsualArithmeticConversions() |
| static QualType handleFloatConversion(Sema &S, ExprResult &LHS, |
| ExprResult &RHS, QualType LHSType, |
| QualType RHSType, bool IsCompAssign) { |
| bool LHSFloat = LHSType->isRealFloatingType(); |
| bool RHSFloat = RHSType->isRealFloatingType(); |
| |
| // If we have two real floating types, convert the smaller operand |
| // to the bigger result. |
| if (LHSFloat && RHSFloat) { |
| int order = S.Context.getFloatingTypeOrder(LHSType, RHSType); |
| if (order > 0) { |
| RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FloatingCast); |
| return LHSType; |
| } |
| |
| assert(order < 0 && "illegal float comparison"); |
| if (!IsCompAssign) |
| LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FloatingCast); |
| return RHSType; |
| } |
| |
| if (LHSFloat) { |
| // Half FP has to be promoted to float unless it is natively supported |
| if (LHSType->isHalfType() && !S.getLangOpts().NativeHalfType) |
| LHSType = S.Context.FloatTy; |
| |
| return handleIntToFloatConversion(S, LHS, RHS, LHSType, RHSType, |
| /*convertFloat=*/!IsCompAssign, |
| /*convertInt=*/ true); |
| } |
| assert(RHSFloat); |
| return handleIntToFloatConversion(S, RHS, LHS, RHSType, LHSType, |
| /*convertInt=*/ true, |
| /*convertFloat=*/!IsCompAssign); |
| } |
| |
| /// \brief Diagnose attempts to convert between __float128 and long double if |
| /// there is no support for such conversion. Helper function of |
| /// UsualArithmeticConversions(). |
| static bool unsupportedTypeConversion(const Sema &S, QualType LHSType, |
| QualType RHSType) { |
| /* No issue converting if at least one of the types is not a floating point |
| type or the two types have the same rank. |
| */ |
| if (!LHSType->isFloatingType() || !RHSType->isFloatingType() || |
| S.Context.getFloatingTypeOrder(LHSType, RHSType) == 0) |
| return false; |
| |
| assert(LHSType->isFloatingType() && RHSType->isFloatingType() && |
| "The remaining types must be floating point types."); |
| |
| auto *LHSComplex = LHSType->getAs<ComplexType>(); |
| auto *RHSComplex = RHSType->getAs<ComplexType>(); |
| |
| QualType LHSElemType = LHSComplex ? |
| LHSComplex->getElementType() : LHSType; |
| QualType RHSElemType = RHSComplex ? |
| RHSComplex->getElementType() : RHSType; |
| |
| // No issue if the two types have the same representation |
| if (&S.Context.getFloatTypeSemantics(LHSElemType) == |
| &S.Context.getFloatTypeSemantics(RHSElemType)) |
| return false; |
| |
| bool Float128AndLongDouble = (LHSElemType == S.Context.Float128Ty && |
| RHSElemType == S.Context.LongDoubleTy); |
| Float128AndLongDouble |= (LHSElemType == S.Context.LongDoubleTy && |
| RHSElemType == S.Context.Float128Ty); |
| |
| /* We've handled the situation where __float128 and long double have the same |
| representation. The only other allowable conversion is if long double is |
| really just double. |
| */ |
| return Float128AndLongDouble && |
| (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) != |
| &llvm::APFloat::IEEEdouble()); |
| } |
| |
| typedef ExprResult PerformCastFn(Sema &S, Expr *operand, QualType toType); |
| |
| namespace { |
| /// These helper callbacks are placed in an anonymous namespace to |
| /// permit their use as function template parameters. |
| ExprResult doIntegralCast(Sema &S, Expr *op, QualType toType) { |
| return S.ImpCastExprToType(op, toType, CK_IntegralCast); |
| } |
| |
| ExprResult doComplexIntegralCast(Sema &S, Expr *op, QualType toType) { |
| return S.ImpCastExprToType(op, S.Context.getComplexType(toType), |
| CK_IntegralComplexCast); |
| } |
| } |
| |
| /// \brief Handle integer arithmetic conversions. Helper function of |
| /// UsualArithmeticConversions() |
| template <PerformCastFn doLHSCast, PerformCastFn doRHSCast> |
| static QualType handleIntegerConversion(Sema &S, ExprResult &LHS, |
| ExprResult &RHS, QualType LHSType, |
| QualType RHSType, bool IsCompAssign) { |
| // The rules for this case are in C99 6.3.1.8 |
| int order = S.Context.getIntegerTypeOrder(LHSType, RHSType); |
| bool LHSSigned = LHSType->hasSignedIntegerRepresentation(); |
| bool RHSSigned = RHSType->hasSignedIntegerRepresentation(); |
| if (LHSSigned == RHSSigned) { |
| // Same signedness; use the higher-ranked type |
| if (order >= 0) { |
| RHS = (*doRHSCast)(S, RHS.get(), LHSType); |
| return LHSType; |
| } else if (!IsCompAssign) |
| LHS = (*doLHSCast)(S, LHS.get(), RHSType); |
| return RHSType; |
| } else if (order != (LHSSigned ? 1 : -1)) { |
| // The unsigned type has greater than or equal rank to the |
| // signed type, so use the unsigned type |
| if (RHSSigned) { |
| RHS = (*doRHSCast)(S, RHS.get(), LHSType); |
| return LHSType; |
| } else if (!IsCompAssign) |
| LHS = (*doLHSCast)(S, LHS.get(), RHSType); |
| return RHSType; |
| } else if (S.Context.getIntWidth(LHSType) != S.Context.getIntWidth(RHSType)) { |
| // The two types are different widths; if we are here, that |
| // means the signed type is larger than the unsigned type, so |
| // use the signed type. |
| if (LHSSigned) { |
| RHS = (*doRHSCast)(S, RHS.get(), LHSType); |
| return LHSType; |
| } else if (!IsCompAssign) |
| LHS = (*doLHSCast)(S, LHS.get(), RHSType); |
| return RHSType; |
| } else { |
| // The signed type is higher-ranked than the unsigned type, |
| // but isn't actually any bigger (like unsigned int and long |
| // on most 32-bit systems). Use the unsigned type corresponding |
| // to the signed type. |
| QualType result = |
| S.Context.getCorrespondingUnsignedType(LHSSigned ? LHSType : RHSType); |
| RHS = (*doRHSCast)(S, RHS.get(), result); |
| if (!IsCompAssign) |
| LHS = (*doLHSCast)(S, LHS.get(), result); |
| return result; |
| } |
| } |
| |
| /// \brief Handle conversions with GCC complex int extension. Helper function |
| /// of UsualArithmeticConversions() |
| static QualType handleComplexIntConversion(Sema &S, ExprResult &LHS, |
| ExprResult &RHS, QualType LHSType, |
| QualType RHSType, |
| bool IsCompAssign) { |
| const ComplexType *LHSComplexInt = LHSType->getAsComplexIntegerType(); |
| const ComplexType *RHSComplexInt = RHSType->getAsComplexIntegerType(); |
| |
| if (LHSComplexInt && RHSComplexInt) { |
| QualType LHSEltType = LHSComplexInt->getElementType(); |
| QualType RHSEltType = RHSComplexInt->getElementType(); |
| QualType ScalarType = |
| handleIntegerConversion<doComplexIntegralCast, doComplexIntegralCast> |
| (S, LHS, RHS, LHSEltType, RHSEltType, IsCompAssign); |
| |
| return S.Context.getComplexType(ScalarType); |
| } |
| |
| if (LHSComplexInt) { |
| QualType LHSEltType = LHSComplexInt->getElementType(); |
| QualType ScalarType = |
| handleIntegerConversion<doComplexIntegralCast, doIntegralCast> |
| (S, LHS, RHS, LHSEltType, RHSType, IsCompAssign); |
| QualType ComplexType = S.Context.getComplexType(ScalarType); |
| RHS = S.ImpCastExprToType(RHS.get(), ComplexType, |
| CK_IntegralRealToComplex); |
| |
| return ComplexType; |
| } |
| |
| assert(RHSComplexInt); |
| |
| QualType RHSEltType = RHSComplexInt->getElementType(); |
| QualType ScalarType = |
| handleIntegerConversion<doIntegralCast, doComplexIntegralCast> |
| (S, LHS, RHS, LHSType, RHSEltType, IsCompAssign); |
| QualType ComplexType = S.Context.getComplexType(ScalarType); |
| |
| if (!IsCompAssign) |
| LHS = S.ImpCastExprToType(LHS.get(), ComplexType, |
| CK_IntegralRealToComplex); |
| return ComplexType; |
| } |
| |
| /// UsualArithmeticConversions - Performs various conversions that are common to |
| /// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this |
| /// routine returns the first non-arithmetic type found. The client is |
| /// responsible for emitting appropriate error diagnostics. |
| QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, |
| bool IsCompAssign) { |
| if (!IsCompAssign) { |
| LHS = UsualUnaryConversions(LHS.get()); |
| if (LHS.isInvalid()) |
| return QualType(); |
| } |
| |
| RHS = UsualUnaryConversions(RHS.get()); |
| if (RHS.isInvalid()) |
| return QualType(); |
| |
| // For conversion purposes, we ignore any qualifiers. |
| // For example, "const float" and "float" are equivalent. |
| QualType LHSType = |
| Context.getCanonicalType(LHS.get()->getType()).getUnqualifiedType(); |
| QualType RHSType = |
| Context.getCanonicalType(RHS.get()->getType()).getUnqualifiedType(); |
| |
| // For conversion purposes, we ignore any atomic qualifier on the LHS. |
| if (const AtomicType *AtomicLHS = LHSType->getAs<AtomicType>()) |
| LHSType = AtomicLHS->getValueType(); |
| |
| // If both types are identical, no conversion is needed. |
| if (LHSType == RHSType) |
| return LHSType; |
| |
| // If either side is a non-arithmetic type (e.g. a pointer), we are done. |
| // The caller can deal with this (e.g. pointer + int). |
| if (!LHSType->isArithmeticType() || !RHSType->isArithmeticType()) |
| return QualType(); |
| |
| // Apply unary and bitfield promotions to the LHS's type. |
| QualType LHSUnpromotedType = LHSType; |
| if (LHSType->isPromotableIntegerType()) |
| LHSType = Context.getPromotedIntegerType(LHSType); |
| QualType LHSBitfieldPromoteTy = Context.isPromotableBitField(LHS.get()); |
| if (!LHSBitfieldPromoteTy.isNull()) |
| LHSType = LHSBitfieldPromoteTy; |
| if (LHSType != LHSUnpromotedType && !IsCompAssign) |
| LHS = ImpCastExprToType(LHS.get(), LHSType, CK_IntegralCast); |
| |
| // If both types are identical, no conversion is needed. |
| if (LHSType == RHSType) |
| return LHSType; |
| |
| // At this point, we have two different arithmetic types. |
| |
| // Diagnose attempts to convert between __float128 and long double where |
| // such conversions currently can't be handled. |
| if (unsupportedTypeConversion(*this, LHSType, RHSType)) |
| return QualType(); |
| |
| // Handle complex types first (C99 6.3.1.8p1). |
| if (LHSType->isComplexType() || RHSType->isComplexType()) |
| return handleComplexFloatConversion(*this, LHS, RHS, LHSType, RHSType, |
| IsCompAssign); |
| |
| // Now handle "real" floating types (i.e. float, double, long double). |
| if (LHSType->isRealFloatingType() || RHSType->isRealFloatingType()) |
| return handleFloatConversion(*this, LHS, RHS, LHSType, RHSType, |
| IsCompAssign); |
| |
| // Handle GCC complex int extension. |
| if (LHSType->isComplexIntegerType() || RHSType->isComplexIntegerType()) |
| return handleComplexIntConversion(*this, LHS, RHS, LHSType, RHSType, |
| IsCompAssign); |
| |
| // Finally, we have two differing integer types. |
| return handleIntegerConversion<doIntegralCast, doIntegralCast> |
| (*this, LHS, RHS, LHSType, RHSType, IsCompAssign); |
| } |
| |
| |
| //===----------------------------------------------------------------------===// |
| // Semantic Analysis for various Expression Types |
| //===----------------------------------------------------------------------===// |
| |
| |
| ExprResult |
| Sema::ActOnGenericSelectionExpr(SourceLocation KeyLoc, |
| SourceLocation DefaultLoc, |
| SourceLocation RParenLoc, |
| Expr *ControllingExpr, |
| ArrayRef<ParsedType> ArgTypes, |
| ArrayRef<Expr *> ArgExprs) { |
| unsigned NumAssocs = ArgTypes.size(); |
| assert(NumAssocs == ArgExprs.size()); |
| |
| TypeSourceInfo **Types = new TypeSourceInfo*[NumAssocs]; |
| for (unsigned i = 0; i < NumAssocs; ++i) { |
| if (ArgTypes[i]) |
| (void) GetTypeFromParser(ArgTypes[i], &Types[i]); |
| else |
| Types[i] = nullptr; |
| } |
| |
| ExprResult ER = CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc, |
| ControllingExpr, |
| llvm::makeArrayRef(Types, NumAssocs), |
| ArgExprs); |
| delete [] Types; |
| return ER; |
| } |
| |
| ExprResult |
| Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, |
| SourceLocation DefaultLoc, |
| SourceLocation RParenLoc, |
| Expr *ControllingExpr, |
| ArrayRef<TypeSourceInfo *> Types, |
| ArrayRef<Expr *> Exprs) { |
| unsigned NumAssocs = Types.size(); |
| assert(NumAssocs == Exprs.size()); |
| |
| // Decay and strip qualifiers for the controlling expression type, and handle |
| // placeholder type replacement. See committee discussion from WG14 DR423. |
| { |
| EnterExpressionEvaluationContext Unevaluated( |
| *this, Sema::ExpressionEvaluationContext::Unevaluated); |
| ExprResult R = DefaultFunctionArrayLvalueConversion(ControllingExpr); |
| if (R.isInvalid()) |
| return ExprError(); |
| ControllingExpr = R.get(); |
| } |
| |
| // The controlling expression is an unevaluated operand, so side effects are |
| // likely unintended. |
| if (!inTemplateInstantiation() && |
| ControllingExpr->HasSideEffects(Context, false)) |
| Diag(ControllingExpr->getExprLoc(), |
| diag::warn_side_effects_unevaluated_context); |
| |
| bool TypeErrorFound = false, |
| IsResultDependent = ControllingExpr->isTypeDependent(), |
| ContainsUnexpandedParameterPack |
| = ControllingExpr->containsUnexpandedParameterPack(); |
| |
| for (unsigned i = 0; i < NumAssocs; ++i) { |
| if (Exprs[i]->containsUnexpandedParameterPack()) |
| ContainsUnexpandedParameterPack = true; |
| |
| if (Types[i]) { |
| if (Types[i]->getType()->containsUnexpandedParameterPack()) |
| ContainsUnexpandedParameterPack = true; |
| |
| if (Types[i]->getType()->isDependentType()) { |
| IsResultDependent = true; |
| } else { |
| // C11 6.5.1.1p2 "The type name in a generic association shall specify a |
| // complete object type other than a variably modified type." |
| unsigned D = 0; |
| if (Types[i]->getType()->isIncompleteType()) |
| D = diag::err_assoc_type_incomplete; |
| else if (!Types[i]->getType()->isObjectType()) |
| D = diag::err_assoc_type_nonobject; |
| else if (Types[i]->getType()->isVariablyModifiedType()) |
| D = diag::err_assoc_type_variably_modified; |
| |
| if (D != 0) { |
| Diag(Types[i]->getTypeLoc().getBeginLoc(), D) |
| << Types[i]->getTypeLoc().getSourceRange() |
| << Types[i]->getType(); |
| TypeErrorFound = true; |
| } |
| |
| // C11 6.5.1.1p2 "No two generic associations in the same generic |
| // selection shall specify compatible types." |
| for (unsigned j = i+1; j < NumAssocs; ++j) |
| if (Types[j] && !Types[j]->getType()->isDependentType() && |
| Context.typesAreCompatible(Types[i]->getType(), |
| Types[j]->getType())) { |
| Diag(Types[j]->getTypeLoc().getBeginLoc(), |
| diag::err_assoc_compatible_types) |
| << Types[j]->getTypeLoc().getSourceRange() |
| << Types[j]->getType() |
| << Types[i]->getType(); |
| Diag(Types[i]->getTypeLoc().getBeginLoc(), |
| diag::note_compat_assoc) |
| << Types[i]->getTypeLoc().getSourceRange() |
| << Types[i]->getType(); |
| TypeErrorFound = true; |
| } |
| } |
| } |
| } |
| if (TypeErrorFound) |
| return ExprError(); |
| |
| // If we determined that the generic selection is result-dependent, don't |
| // try to compute the result expression. |
| if (IsResultDependent) |
| return new (Context) GenericSelectionExpr( |
| Context, KeyLoc, ControllingExpr, Types, Exprs, DefaultLoc, RParenLoc, |
| ContainsUnexpandedParameterPack); |
| |
| SmallVector<unsigned, 1> CompatIndices; |
| unsigned DefaultIndex = -1U; |
| for (unsigned i = 0; i < NumAssocs; ++i) { |
| if (!Types[i]) |
| DefaultIndex = i; |
| else if (Context.typesAreCompatible(ControllingExpr->getType(), |
| Types[i]->getType())) |
| CompatIndices.push_back(i); |
| } |
| |
| // C11 6.5.1.1p2 "The controlling expression of a generic selection shall have |
| // type compatible with at most one of the types named in its generic |
| // association list." |
| if (CompatIndices.size() > 1) { |
| // We strip parens here because the controlling expression is typically |
| // parenthesized in macro definitions. |
| ControllingExpr = ControllingExpr->IgnoreParens(); |
| Diag(ControllingExpr->getLocStart(), diag::err_generic_sel_multi_match) |
| << ControllingExpr->getSourceRange() << ControllingExpr->getType() |
| << (unsigned) CompatIndices.size(); |
| for (unsigned I : CompatIndices) { |
| Diag(Types[I]->getTypeLoc().getBeginLoc(), |
| diag::note_compat_assoc) |
| << Types[I]->getTypeLoc().getSourceRange() |
| << Types[I]->getType(); |
| } |
| return ExprError(); |
| } |
| |
| // C11 6.5.1.1p2 "If a generic selection has no default generic association, |
| // its controlling expression shall have type compatible with exactly one of |
| // the types named in its generic association list." |
| if (DefaultIndex == -1U && CompatIndices.size() == 0) { |
| // We strip parens here because the controlling expression is typically |
| // parenthesized in macro definitions. |
| ControllingExpr = ControllingExpr->IgnoreParens(); |
| Diag(ControllingExpr->getLocStart(), diag::err_generic_sel_no_match) |
| << ControllingExpr->getSourceRange() << ControllingExpr->getType(); |
| return ExprError(); |
| } |
| |
| // C11 6.5.1.1p3 "If a generic selection has a generic association with a |
| // type name that is compatible with the type of the controlling expression, |
| // then the result expression of the generic selection is the expression |
| // in that generic association. Otherwise, the result expression of the |
| // generic selection is the expression in the default generic association." |
| unsigned ResultIndex = |
| CompatIndices.size() ? CompatIndices[0] : DefaultIndex; |
| |
| return new (Context) GenericSelectionExpr( |
| Context, KeyLoc, ControllingExpr, Types, Exprs, DefaultLoc, RParenLoc, |
| ContainsUnexpandedParameterPack, ResultIndex); |
| } |
| |
| /// getUDSuffixLoc - Create a SourceLocation for a ud-suffix, given the |
| /// location of the token and the offset of the ud-suffix within it. |
| static SourceLocation getUDSuffixLoc(Sema &S, SourceLocation TokLoc, |
| unsigned Offset) { |
| return Lexer::AdvanceToTokenCharacter(TokLoc, Offset, S.getSourceManager(), |
| S.getLangOpts()); |
| } |
| |
| /// BuildCookedLiteralOperatorCall - A user-defined literal was found. Look up |
| /// the corresponding cooked (non-raw) literal operator, and build a call to it. |
| static ExprResult BuildCookedLiteralOperatorCall(Sema &S, Scope *Scope, |
| IdentifierInfo *UDSuffix, |
| SourceLocation UDSuffixLoc, |
| ArrayRef<Expr*> Args, |
| SourceLocation LitEndLoc) { |
| assert(Args.size() <= 2 && "too many arguments for literal operator"); |
| |
| QualType ArgTy[2]; |
| for (unsigned ArgIdx = 0; ArgIdx != Args.size(); ++ArgIdx) { |
| ArgTy[ArgIdx] = Args[ArgIdx]->getType(); |
| if (ArgTy[ArgIdx]->isArrayType()) |
| ArgTy[ArgIdx] = S.Context.getArrayDecayedType(ArgTy[ArgIdx]); |
| } |
| |
| DeclarationName OpName = |
| S.Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix); |
| DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc); |
| OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc); |
| |
| LookupResult R(S, OpName, UDSuffixLoc, Sema::LookupOrdinaryName); |
| if (S.LookupLiteralOperator(Scope, R, llvm::makeArrayRef(ArgTy, Args.size()), |
| /*AllowRaw*/ false, /*AllowTemplate*/ false, |
| /*AllowStringTemplate*/ false, |
| /*DiagnoseMissing*/ true) == Sema::LOLR_Error) |
| return ExprError(); |
| |
| return S.BuildLiteralOperatorCall(R, OpNameInfo, Args, LitEndLoc); |
| } |
| |
| /// ActOnStringLiteral - The specified tokens were lexed as pasted string |
| /// fragments (e.g. "foo" "bar" L"baz"). The result string has to handle string |
| /// concatenation ([C99 5.1.1.2, translation phase #6]), so it may come from |
| /// multiple tokens. However, the common case is that StringToks points to one |
| /// string. |
| /// |
| ExprResult |
| Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) { |
| assert(!StringToks.empty() && "Must have at least one string!"); |
| |
| StringLiteralParser Literal(StringToks, PP); |
| if (Literal.hadError) |
| return ExprError(); |
| |
| SmallVector<SourceLocation, 4> StringTokLocs; |
| for (const Token &Tok : StringToks) |
| StringTokLocs.push_back(Tok.getLocation()); |
| |
| QualType CharTy = Context.CharTy; |
| StringLiteral::StringKind Kind = StringLiteral::Ascii; |
| if (Literal.isWide()) { |
| CharTy = Context.getWideCharType(); |
| Kind = StringLiteral::Wide; |
| } else if (Literal.isUTF8()) { |
| Kind = StringLiteral::UTF8; |
| } else if (Literal.isUTF16()) { |
| CharTy = Context.Char16Ty; |
| Kind = StringLiteral::UTF16; |
| } else if (Literal.isUTF32()) { |
| CharTy = Context.Char32Ty; |
| Kind = StringLiteral::UTF32; |
| } else if (Literal.isPascal()) { |
| CharTy = Context.UnsignedCharTy; |
| } |
| |
| QualType CharTyConst = CharTy; |
| // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). |
| if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings) |
| CharTyConst.addConst(); |
| |
| // Get an array type for the string, according to C99 6.4.5. This includes |
| // the nul terminator character as well as the string length for pascal |
| // strings. |
| QualType StrTy = Context.getConstantArrayType(CharTyConst, |
| llvm::APInt(32, Literal.GetNumStringChars()+1), |
| ArrayType::Normal, 0); |
| |
| // OpenCL v1.1 s6.5.3: a string literal is in the constant address space. |
| if (getLangOpts().OpenCL) { |
| StrTy = Context.getAddrSpaceQualType(StrTy, LangAS::opencl_constant); |
| } |
| |
| // Pass &StringTokLocs[0], StringTokLocs.size() to factory! |
| StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(), |
| Kind, Literal.Pascal, StrTy, |
| &StringTokLocs[0], |
| StringTokLocs.size()); |
| if (Literal.getUDSuffix().empty()) |
| return Lit; |
| |
| // We're building a user-defined literal. |
| IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix()); |
| SourceLocation UDSuffixLoc = |
| getUDSuffixLoc(*this, StringTokLocs[Literal.getUDSuffixToken()], |
| Literal.getUDSuffixOffset()); |
| |
| // Make sure we're allowed user-defined literals here. |
| if (!UDLScope) |
| return ExprError(Diag(UDSuffixLoc, diag::err_invalid_string_udl)); |
| |
| // C++11 [lex.ext]p5: The literal L is treated as a call of the form |
| // operator "" X (str, len) |
| QualType SizeType = Context.getSizeType(); |
| |
| DeclarationName OpName = |
| Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix); |
| DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc); |
| OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc); |
| |
| QualType ArgTy[] = { |
| Context.getArrayDecayedType(StrTy), SizeType |
| }; |
| |
| LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName); |
| switch (LookupLiteralOperator(UDLScope, R, ArgTy, |
| /*AllowRaw*/ false, /*AllowTemplate*/ false, |
| /*AllowStringTemplate*/ true, |
| /*DiagnoseMissing*/ true)) { |
| |
| case LOLR_Cooked: { |
| llvm::APInt Len(Context.getIntWidth(SizeType), Literal.GetNumStringChars()); |
| IntegerLiteral *LenArg = IntegerLiteral::Create(Context, Len, SizeType, |
| StringTokLocs[0]); |
| Expr *Args[] = { Lit, LenArg }; |
| |
| return BuildLiteralOperatorCall(R, OpNameInfo, Args, StringTokLocs.back()); |
| } |
| |
| case LOLR_StringTemplate: { |
| TemplateArgumentListInfo ExplicitArgs; |
| |
| unsigned CharBits = Context.getIntWidth(CharTy); |
| bool CharIsUnsigned = CharTy->isUnsignedIntegerType(); |
| llvm::APSInt Value(CharBits, CharIsUnsigned); |
| |
| TemplateArgument TypeArg(CharTy); |
| TemplateArgumentLocInfo TypeArgInfo(Context.getTrivialTypeSourceInfo(CharTy)); |
| ExplicitArgs.addArgument(TemplateArgumentLoc(TypeArg, TypeArgInfo)); |
| |
| for (unsigned I = 0, N = Lit->getLength(); I != N; ++I) { |
| Value = Lit->getCodeUnit(I); |
| TemplateArgument Arg(Context, Value, CharTy); |
| TemplateArgumentLocInfo ArgInfo; |
| ExplicitArgs.addArgument(TemplateArgumentLoc(Arg, ArgInfo)); |
| } |
| return BuildLiteralOperatorCall(R, OpNameInfo, None, StringTokLocs.back(), |
| &ExplicitArgs); |
| } |
| case LOLR_Raw: |
| case LOLR_Template: |
| case LOLR_ErrorNoDiagnostic: |
| llvm_unreachable("unexpected literal operator lookup result"); |
| case LOLR_Error: |
| return ExprError(); |
| } |
| llvm_unreachable("unexpected literal operator lookup result"); |
| } |
| |
| ExprResult |
| Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, |
| SourceLocation Loc, |
| const CXXScopeSpec *SS) { |
| DeclarationNameInfo NameInfo(D->getDeclName(), Loc); |
| return BuildDeclRefExpr(D, Ty, VK, NameInfo, SS); |
| } |
| |
| /// BuildDeclRefExpr - Build an expression that references a |
| /// declaration that does not require a closure capture. |
| ExprResult |
| Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, |
| const DeclarationNameInfo &NameInfo, |
| const CXXScopeSpec *SS, NamedDecl *FoundD, |
| const TemplateArgumentListInfo *TemplateArgs) { |
| bool RefersToCapturedVariable = |
| isa<VarDecl>(D) && |
| NeedToCaptureVariable(cast<VarDecl>(D), NameInfo.getLoc()); |
| |
| DeclRefExpr *E; |
| if (isa<VarTemplateSpecializationDecl>(D)) { |
| VarTemplateSpecializationDecl *VarSpec = |
| cast<VarTemplateSpecializationDecl>(D); |
| |
| E = DeclRefExpr::Create(Context, SS ? SS->getWithLocInContext(Context) |
| : NestedNameSpecifierLoc(), |
| VarSpec->getTemplateKeywordLoc(), D, |
| RefersToCapturedVariable, NameInfo.getLoc(), Ty, VK, |
| FoundD, TemplateArgs); |
| } else { |
| assert(!TemplateArgs && "No template arguments for non-variable" |
| " template specialization references"); |
| E = DeclRefExpr::Create(Context, SS ? SS->getWithLocInContext(Context) |
| : NestedNameSpecifierLoc(), |
| SourceLocation(), D, RefersToCapturedVariable, |
| NameInfo, Ty, VK, FoundD); |
| } |
| |
| MarkDeclRefReferenced(E); |
| |
| if (getLangOpts().ObjCWeak && isa<VarDecl>(D) && |
| Ty.getObjCLifetime() == Qualifiers::OCL_Weak && |
| !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getLocStart())) |
| recordUseOfEvaluatedWeak(E); |
| |
| FieldDecl *FD = dyn_cast<FieldDecl>(D); |
| if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(D)) |
| FD = IFD->getAnonField(); |
| if (FD) { |
| UnusedPrivateFields.remove(FD); |
| // Just in case we're building an illegal pointer-to-member. |
| if (FD->isBitField()) |
| E->setObjectKind(OK_BitField); |
| } |
| |
| // C++ [expr.prim]/8: The expression [...] is a bit-field if the identifier |
| // designates a bit-field. |
| if (auto *BD = dyn_cast<BindingDecl>(D)) |
| if (auto *BE = BD->getBinding()) |
| E->setObjectKind(BE->getObjectKind()); |
| |
| return E; |
| } |
| |
| /// Decomposes the given name into a DeclarationNameInfo, its location, and |
| /// possibly a list of template arguments. |
| /// |
| /// If this produces template arguments, it is permitted to call |
| /// DecomposeTemplateName. |
| /// |
| /// This actually loses a lot of source location information for |
| /// non-standard name kinds; we should consider preserving that in |
| /// some way. |
| void |
| Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id, |
| TemplateArgumentListInfo &Buffer, |
| DeclarationNameInfo &NameInfo, |
| const TemplateArgumentListInfo *&TemplateArgs) { |
| if (Id.getKind() == UnqualifiedIdKind::IK_TemplateId) { |
| Buffer.setLAngleLoc(Id.TemplateId->LAngleLoc); |
| Buffer.setRAngleLoc(Id.TemplateId->RAngleLoc); |
| |
| ASTTemplateArgsPtr TemplateArgsPtr(Id.TemplateId->getTemplateArgs(), |
| Id.TemplateId->NumArgs); |
| translateTemplateArguments(TemplateArgsPtr, Buffer); |
| |
| TemplateName TName = Id.TemplateId->Template.get(); |
| SourceLocation TNameLoc = Id.TemplateId->TemplateNameLoc; |
| NameInfo = Context.getNameForTemplate(TName, TNameLoc); |
| TemplateArgs = &Buffer; |
| } else { |
| NameInfo = GetNameFromUnqualifiedId(Id); |
| TemplateArgs = nullptr; |
| } |
| } |
| |
| static void emitEmptyLookupTypoDiagnostic( |
| const TypoCorrection &TC, Sema &SemaRef, const CXXScopeSpec &SS, |
| DeclarationName Typo, SourceLocation TypoLoc, ArrayRef<Expr *> Args, |
| unsigned DiagnosticID, unsigned DiagnosticSuggestID) { |
| DeclContext *Ctx = |
| SS.isEmpty() ? nullptr : SemaRef.computeDeclContext(SS, false); |
| if (!TC) { |
| // Emit a special diagnostic for failed member lookups. |
| // FIXME: computing the declaration context might fail here (?) |
| if (Ctx) |
| SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << Ctx |
| << SS.getRange(); |
| else |
| SemaRef.Diag(TypoLoc, DiagnosticID) << Typo; |
| return; |
| } |
| |
| std::string CorrectedStr = TC.getAsString(SemaRef.getLangOpts()); |
| bool DroppedSpecifier = |
| TC.WillReplaceSpecifier() && Typo.getAsString() == CorrectedStr; |
| unsigned NoteID = TC.getCorrectionDeclAs<ImplicitParamDecl>() |
| ? diag::note_implicit_param_decl |
| : diag::note_previous_decl; |
| if (!Ctx) |
| SemaRef.diagnoseTypo(TC, SemaRef.PDiag(DiagnosticSuggestID) << Typo, |
| SemaRef.PDiag(NoteID)); |
| else |
| SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest) |
| << Typo << Ctx << DroppedSpecifier |
| << SS.getRange(), |
| SemaRef.PDiag(NoteID)); |
| } |
| |
| /// Diagnose an empty lookup. |
| /// |
| /// \return false if new lookup candidates were found |
| bool |
| Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, |
| std::unique_ptr<CorrectionCandidateCallback> CCC, |
| TemplateArgumentListInfo *ExplicitTemplateArgs, |
| ArrayRef<Expr *> Args, TypoExpr **Out) { |
| DeclarationName Name = R.getLookupName(); |
| |
| unsigned diagnostic = diag::err_undeclared_var_use; |
| unsigned diagnostic_suggest = diag::err_undeclared_var_use_suggest; |
| if (Name.getNameKind() == DeclarationName::CXXOperatorName || |
| Name.getNameKind() == DeclarationName::CXXLiteralOperatorName || |
| Name.getNameKind() == DeclarationName::CXXConversionFunctionName) { |
| diagnostic = diag::err_undeclared_use; |
| diagnostic_suggest = diag::err_undeclared_use_suggest; |
| } |
| |
| // If the original lookup was an unqualified lookup, fake an |
| // unqualified lookup. This is useful when (for example) the |
| // original lookup would not have found something because it was a |
| // dependent name. |
| DeclContext *DC = SS.isEmpty() ? CurContext : nullptr; |
| while (DC) { |
| if (isa<CXXRecordDecl>(DC)) { |
| LookupQualifiedName(R, DC); |
| |
| if (!R.empty()) { |
| // Don't give errors about ambiguities in this lookup. |
| R.suppressDiagnostics(); |
| |
| // During a default argument instantiation the CurContext points |
| // to a CXXMethodDecl; but we can't apply a this-> fixit inside a |
| // function parameter list, hence add an explicit check. |
| bool isDefaultArgument = |
| !CodeSynthesisContexts.empty() && |
| CodeSynthesisContexts.back().Kind == |
| CodeSynthesisContext::DefaultFunctionArgumentInstantiation; |
| CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext); |
| bool isInstance = CurMethod && |
| CurMethod->isInstance() && |
| DC == CurMethod->getParent() && !isDefaultArgument; |
| |
| // Give a code modification hint to insert 'this->'. |
| // TODO: fixit for inserting 'Base<T>::' in the other cases. |
| // Actually quite difficult! |
| if (getLangOpts().MSVCCompat) |
| diagnostic = diag::ext_found_via_dependent_bases_lookup; |
| if (isInstance) { |
| Diag(R.getNameLoc(), diagnostic) << Name |
| << FixItHint::CreateInsertion(R.getNameLoc(), "this->"); |
| CheckCXXThisCapture(R.getNameLoc()); |
| } else { |
| Diag(R.getNameLoc(), diagnostic) << Name; |
| } |
| |
| // Do we really want to note all of these? |
| for (NamedDecl *D : R) |
| Diag(D->getLocation(), diag::note_dependent_var_use); |
| |
| // Return true if we are inside a default argument instantiation |
| // and the found name refers to an instance member function, otherwise |
| // the function calling DiagnoseEmptyLookup will try to create an |
| // implicit member call and this is wrong for default argument. |
| if (isDefaultArgument && ((*R.begin())->isCXXInstanceMember())) { |
| Diag(R.getNameLoc(), diag::err_member_call_without_object); |
| return true; |
| } |
| |
| // Tell the callee to try to recover. |
| return false; |
| } |
| |
| R.clear(); |
| } |
| |
| // In Microsoft mode, if we are performing lookup from within a friend |
| // function definition declared at class scope then we must set |
| // DC to the lexical parent to be able to search into the parent |
| // class. |
| if (getLangOpts().MSVCCompat && isa<FunctionDecl>(DC) && |
| cast<FunctionDecl>(DC)->getFriendObjectKind() && |
| DC->getLexicalParent()->isRecord()) |
| DC = DC->getLexicalParent(); |
| else |
| DC = DC->getParent(); |
| } |
| |
| // We didn't find anything, so try to correct for a typo. |
| TypoCorrection Corrected; |
| if (S && Out) { |
| SourceLocation TypoLoc = R.getNameLoc(); |
| assert(!ExplicitTemplateArgs && |
| "Diagnosing an empty lookup with explicit template args!"); |
| *Out = CorrectTypoDelayed( |
| R.getLookupNameInfo(), R.getLookupKind(), S, &SS, std::move(CCC), |
| [=](const TypoCorrection &TC) { |
| emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, TypoLoc, Args, |
| diagnostic, diagnostic_suggest); |
| }, |
| nullptr, CTK_ErrorRecovery); |
| if (*Out) |
| return true; |
| } else if (S && (Corrected = |
| CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, |
| &SS, std::move(CCC), CTK_ErrorRecovery))) { |
| std::string CorrectedStr(Corrected.getAsString(getLangOpts())); |
| bool DroppedSpecifier = |
| Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; |
| R.setLookupName(Corrected.getCorrection()); |
| |
| bool AcceptableWithRecovery = false; |
| bool AcceptableWithoutRecovery = false; |
| NamedDecl *ND = Corrected.getFoundDecl(); |
| if (ND) { |
| if (Corrected.isOverloaded()) { |
| OverloadCandidateSet OCS(R.getNameLoc(), |
| OverloadCandidateSet::CSK_Normal); |
| OverloadCandidateSet::iterator Best; |
| for (NamedDecl *CD : Corrected) { |
| if (FunctionTemplateDecl *FTD = |
| dyn_cast<FunctionTemplateDecl>(CD)) |
| AddTemplateOverloadCandidate( |
| FTD, DeclAccessPair::make(FTD, AS_none), ExplicitTemplateArgs, |
| Args, OCS); |
| else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) |
| if (!ExplicitTemplateArgs || ExplicitTemplateArgs->size() == 0) |
| AddOverloadCandidate(FD, DeclAccessPair::make(FD, AS_none), |
| Args, OCS); |
| } |
| switch (OCS.BestViableFunction(*this, R.getNameLoc(), Best)) { |
| case OR_Success: |
| ND = Best->FoundDecl; |
| Corrected.setCorrectionDecl(ND); |
| break; |
| default: |
| // FIXME: Arbitrarily pick the first declaration for the note. |
| Corrected.setCorrectionDecl(ND); |
| break; |
| } |
| } |
| R.addDecl(ND); |
| if (getLangOpts().CPlusPlus && ND->isCXXClassMember()) { |
| CXXRecordDecl *Record = nullptr; |
| if (Corrected.getCorrectionSpecifier()) { |
| const Type *Ty = Corrected.getCorrectionSpecifier()->getAsType(); |
| Record = Ty->getAsCXXRecordDecl(); |
| } |
| if (!Record) |
| Record = cast<CXXRecordDecl>( |
| ND->getDeclContext()->getRedeclContext()); |
| R.setNamingClass(Record); |
| } |
| |
| auto *UnderlyingND = ND->getUnderlyingDecl(); |
| AcceptableWithRecovery = isa<ValueDecl>(UnderlyingND) || |
| isa<FunctionTemplateDecl>(UnderlyingND); |
| // FIXME: If we ended up with a typo for a type name or |
| // Objective-C class name, we're in trouble because the parser |
| // is in the wrong place to recover. Suggest the typo |
| // correction, but don't make it a fix-it since we're not going |
| // to recover well anyway. |
| AcceptableWithoutRecovery = |
| isa<TypeDecl>(UnderlyingND) || isa<ObjCInterfaceDecl>(UnderlyingND); |
| } else { |
| // FIXME: We found a keyword. Suggest it, but don't provide a fix-it |
| // because we aren't able to recover. |
| AcceptableWithoutRecovery = true; |
| } |
| |
| if (AcceptableWithRecovery || AcceptableWithoutRecovery) { |
| unsigned NoteID = Corrected.getCorrectionDeclAs<ImplicitParamDecl>() |
| ? diag::note_implicit_param_decl |
| : diag::note_previous_decl; |
| if (SS.isEmpty()) |
| diagnoseTypo(Corrected, PDiag(diagnostic_suggest) << Name, |
| PDiag(NoteID), AcceptableWithRecovery); |
| else |
| diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest) |
| << Name << computeDeclContext(SS, false) |
| << DroppedSpecifier << SS.getRange(), |
| PDiag(NoteID), AcceptableWithRecovery); |
| |
| // Tell the callee whether to try to recover. |
| return !AcceptableWithRecovery; |
| } |
| } |
| R.clear(); |
| |
| // Emit a special diagnostic for failed member lookups. |
| // FIXME: computing the declaration context might fail here (?) |
| if (!SS.isEmpty()) { |
| Diag(R.getNameLoc(), diag::err_no_member) |
| << Name << computeDeclContext(SS, false) |
| << SS.getRange(); |
| return true; |
| } |
| |
| // Give up, we can't recover. |
| Diag(R.getNameLoc(), diagnostic) << Name; |
| return true; |
| } |
| |
| /// In Microsoft mode, if we are inside a template class whose parent class has |
| /// dependent base classes, and we can't resolve an unqualified identifier, then |
| /// assume the identifier is a member of a dependent base class. We can only |
| /// recover successfully in static methods, instance methods, and other contexts |
| /// where 'this' is available. This doesn't precisely match MSVC's |
| /// instantiation model, but it's close enough. |
| static Expr * |
| recoverFromMSUnqualifiedLookup(Sema &S, ASTContext &Context, |
| DeclarationNameInfo &NameInfo, |
| SourceLocation TemplateKWLoc, |
| const TemplateArgumentListInfo *TemplateArgs) { |
| // Only try to recover from lookup into dependent bases in static methods or |
| // contexts where 'this' is available. |
| QualType ThisType = S.getCurrentThisType(); |
| const CXXRecordDecl *RD = nullptr; |
| if (!ThisType.isNull()) |
| RD = ThisType->getPointeeType()->getAsCXXRecordDecl(); |
| else if (auto *MD = dyn_cast<CXXMethodDecl>(S.CurContext)) |
| RD = MD->getParent(); |
| if (!RD || !RD->hasAnyDependentBases()) |
| return nullptr; |
| |
| // Diagnose this as unqualified lookup into a dependent base class. If 'this' |
| // is available, suggest inserting 'this->' as a fixit. |
| SourceLocation Loc = NameInfo.getLoc(); |
| auto DB = S.Diag(Loc, diag::ext_undeclared_unqual_id_with_dependent_base); |
| DB << NameInfo.getName() << RD; |
| |
| if (!ThisType.isNull()) { |
| DB << FixItHint::CreateInsertion(Loc, "this->"); |
| return CXXDependentScopeMemberExpr::Create( |
| Context, /*This=*/nullptr, ThisType, /*IsArrow=*/true, |
| /*Op=*/SourceLocation(), NestedNameSpecifierLoc(), TemplateKWLoc, |
| /*FirstQualifierInScope=*/nullptr, NameInfo, TemplateArgs); |
| } |
| |
| // Synthesize a fake NNS that points to the derived class. This will |
| // perform name lookup during template instantiation. |
| CXXScopeSpec SS; |
| auto *NNS = |
| NestedNameSpecifier::Create(Context, nullptr, true, RD->getTypeForDecl()); |
| SS.MakeTrivial(Context, NNS, SourceRange(Loc, Loc)); |
| return DependentScopeDeclRefExpr::Create( |
| Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo, |
| TemplateArgs); |
| } |
| |
| ExprResult |
| Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, |
| SourceLocation TemplateKWLoc, UnqualifiedId &Id, |
| bool HasTrailingLParen, bool IsAddressOfOperand, |
| std::unique_ptr<CorrectionCandidateCallback> CCC, |
| bool IsInlineAsmIdentifier, Token *KeywordReplacement) { |
| assert(!(IsAddressOfOperand && HasTrailingLParen) && |
| "cannot be direct & operand and have a trailing lparen"); |
| if (SS.isInvalid()) |
| return ExprError(); |
| |
| TemplateArgumentListInfo TemplateArgsBuffer; |
| |
| // Decompose the UnqualifiedId into the following data. |
| DeclarationNameInfo NameInfo; |
| const TemplateArgumentListInfo *TemplateArgs; |
| DecomposeUnqualifiedId(Id, TemplateArgsBuffer, NameInfo, TemplateArgs); |
| |
| DeclarationName Name = NameInfo.getName(); |
| IdentifierInfo *II = Name.getAsIdentifierInfo(); |
| SourceLocation NameLoc = NameInfo.getLoc(); |
| |
| if (II && II->isEditorPlaceholder()) { |
| // FIXME: When typed placeholders are supported we can create a typed |
| // placeholder expression node. |
| return ExprError(); |
| } |
| |
| // C++ [temp.dep.expr]p3: |
| // An id-expression is type-dependent if it contains: |
| // -- an identifier that was declared with a dependent type, |
| // (note: handled after lookup) |
| // -- a template-id that is dependent, |
| // (note: handled in BuildTemplateIdExpr) |
| // -- a conversion-function-id that specifies a dependent type, |
| // -- a nested-name-specifier that contains a class-name that |
| // names a dependent type. |
| // Determine whether this is a member of an unknown specialization; |
| // we need to handle these differently. |
| bool DependentID = false; |
| if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName && |
| Name.getCXXNameType()->isDependentType()) { |
| DependentID = true; |
| } else if (SS.isSet()) { |
| if (DeclContext *DC = computeDeclContext(SS, false)) { |
| if (RequireCompleteDeclContext(SS, DC)) |
| return ExprError(); |
| } else { |
| DependentID = true; |
| } |
| } |
| |
| if (DependentID) |
| return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, |
| IsAddressOfOperand, TemplateArgs); |
| |
| // Perform the required lookup. |
| LookupResult R(*this, NameInfo, |
| (Id.getKind() == UnqualifiedIdKind::IK_ImplicitSelfParam) |
| ? LookupObjCImplicitSelfParam |
| : LookupOrdinaryName); |
| if (TemplateArgs) { |
| // Lookup the template name again to correctly establish the context in |
| // which it was found. This is really unfortunate as we already did the |
| // lookup to determine that it was a template name in the first place. If |
| // this becomes a performance hit, we can work harder to preserve those |
| // results until we get here but it's likely not worth it. |
| bool MemberOfUnknownSpecialization; |
| LookupTemplateName(R, S, SS, QualType(), /*EnteringContext=*/false, |
| MemberOfUnknownSpecialization); |
| |
| if (MemberOfUnknownSpecialization || |
| (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation)) |
| return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, |
| IsAddressOfOperand, TemplateArgs); |
| } else { |
| bool IvarLookupFollowUp = II && !SS.isSet() && getCurMethodDecl(); |
| LookupParsedName(R, S, &SS, !IvarLookupFollowUp); |
| |
| // If the result might be in a dependent base class, this is a dependent |
| // id-expression. |
| if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation) |
| return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, |
| IsAddressOfOperand, TemplateArgs); |
| |
| // If this reference is in an Objective-C method, then we need to do |
| // some special Objective-C lookup, too. |
| if (IvarLookupFollowUp) { |
| ExprResult E(LookupInObjCMethod(R, S, II, true)); |
| if (E.isInvalid()) |
| return ExprError(); |
| |
| if (Expr *Ex = E.getAs<Expr>()) |
| return Ex; |
| } |
| } |
| |
| if (R.isAmbiguous()) |
| return ExprError(); |
| |
| // This could be an implicitly declared function reference (legal in C90, |
| // extension in C99, forbidden in C++). |
| if (R.empty() && HasTrailingLParen && II && !getLangOpts().CPlusPlus) { |
| NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S); |
| if (D) R.addDecl(D); |
| } |
| |
| // Determine whether this name might be a candidate for |
| // argument-dependent lookup. |
| bool ADL = UseArgumentDependentLookup(SS, R, HasTrailingLParen); |
| |
| if (R.empty() && !ADL) { |
| if (SS.isEmpty() && getLangOpts().MSVCCompat) { |
| if (Expr *E = recoverFromMSUnqualifiedLookup(*this, Context, NameInfo, |
| TemplateKWLoc, TemplateArgs)) |
| return E; |
| } |
| |
| // Don't diagnose an empty lookup for inline assembly. |
| if (IsInlineAsmIdentifier) |
| return ExprError(); |
| |
| // If this name wasn't predeclared and if this is not a function |
| // call, diagnose the problem. |
| TypoExpr *TE = nullptr; |
| auto DefaultValidator = llvm::make_unique<CorrectionCandidateCallback>( |
| II, SS.isValid() ? SS.getScopeRep() : nullptr); |
| DefaultValidator->IsAddressOfOperand = IsAddressOfOperand; |
| assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) && |
| "Typo correction callback misconfigured"); |
| if (CCC) { |
| // Make sure the callback knows what the typo being diagnosed is. |
| CCC->setTypoName(II); |
| if (SS.isValid()) |
| CCC->setTypoNNS(SS.getScopeRep()); |
| } |
| if (DiagnoseEmptyLookup(S, SS, R, |
| CCC ? std::move(CCC) : std::move(DefaultValidator), |
| nullptr, None, &TE)) { |
| if (TE && KeywordReplacement) { |
| auto &State = getTypoExprState(TE); |
| auto BestTC = State.Consumer->getNextCorrection(); |
| if (BestTC.isKeyword()) { |
| auto *II = BestTC.getCorrectionAsIdentifierInfo(); |
| if (State.DiagHandler) |
| State.DiagHandler(BestTC); |
| KeywordReplacement->startToken(); |
| KeywordReplacement->setKind(II->getTokenID()); |
| KeywordReplacement->setIdentifierInfo(II); |
| KeywordReplacement->setLocation(BestTC.getCorrectionRange().getBegin()); |
| // Clean up the state associated with the TypoExpr, since it has |
| // now been diagnosed (without a call to CorrectDelayedTyposInExpr). |
| clearDelayedTypo(TE); |
| // Signal that a correction to a keyword was performed by returning a |
| // valid-but-null ExprResult. |
| return (Expr*)nullptr; |
| } |
| State.Consumer->resetCorrectionStream(); |
| } |
| return TE ? TE : ExprError(); |
| } |
| |
| assert(!R.empty() && |
| "DiagnoseEmptyLookup returned false but added no results"); |
| |
| // If we found an Objective-C instance variable, let |
| // LookupInObjCMethod build the appropriate expression to |
| // reference the ivar. |
| if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) { |
| R.clear(); |
| ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier())); |
| // In a hopelessly buggy code, Objective-C instance variable |
| // lookup fails and no expression will be built to reference it. |
| if (!E.isInvalid() && !E.get()) |
| return ExprError(); |
| return E; |
| } |
| } |
| |
| // This is guaranteed from this point on. |
| assert(!R.empty() || ADL); |
| |
| // Check whether this might be a C++ implicit instance member access. |
| // C++ [class.mfct.non-static]p3: |
| // When an id-expression that is not part of a class member access |
| // syntax and not used to form a pointer to member is used in the |
| // body of a non-static member function of class X, if name lookup |
| // resolves the name in the id-expression to a non-static non-type |
| // member of some class C, the id-expression is transformed into a |
| // class member access expression using (*this) as the |
| // postfix-expression to the left of the . operator. |
| // |
| // But we don't actually need to do this for '&' operands if R |
| // resolved to a function or overloaded function set, because the |
| // expression is ill-formed if it actually works out to be a |
| // non-static member function: |
| // |
| // C++ [expr.ref]p4: |
| // Otherwise, if E1.E2 refers to a non-static member function. . . |
| // [t]he expression can be used only as the left-hand operand of a |
| // member function call. |
| // |
| // There are other safeguards against such uses, but it's important |
| // to get this right here so that we don't end up making a |
| // spuriously dependent expression if we're inside a dependent |
| // instance method. |
| if (!R.empty() && (*R.begin())->isCXXClassMember()) { |
| bool MightBeImplicitMember; |
| if (!IsAddressOfOperand) |
| MightBeImplicitMember = true; |
| else if (!SS.isEmpty()) |
| MightBeImplicitMember = false; |
| else if (R.isOverloadedResult()) |
| MightBeImplicitMember = false; |
| else if (R.isUnresolvableResult()) |
| MightBeImplicitMember = true; |
| else |
| MightBeImplicitMember = isa<FieldDecl>(R.getFoundDecl()) || |
| isa<IndirectFieldDecl>(R.getFoundDecl()) || |
| isa<MSPropertyDecl>(R.getFoundDecl()); |
| |
| if (MightBeImplicitMember) |
| return BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, |
| R, TemplateArgs, S); |
| } |
| |
| if (TemplateArgs || TemplateKWLoc.isValid()) { |
| |
| // In C++1y, if this is a variable template id, then check it |
| // in BuildTemplateIdExpr(). |
| // The single lookup result must be a variable template declaration. |
| if (Id.getKind() == UnqualifiedIdKind::IK_TemplateId && Id.TemplateId && |
| Id.TemplateId->Kind == TNK_Var_template) { |
| assert(R.getAsSingle<VarTemplateDecl>() && |
| "There should only be one declaration found."); |
| } |
| |
| return BuildTemplateIdExpr(SS, TemplateKWLoc, R, ADL, TemplateArgs); |
| } |
| |
| return BuildDeclarationNameExpr(SS, R, ADL); |
| } |
| |
| /// BuildQualifiedDeclarationNameExpr - Build a C++ qualified |
| /// declaration name, generally during template instantiation. |
| /// There's a large number of things which don't need to be done along |
| /// this path. |
| ExprResult Sema::BuildQualifiedDeclarationNameExpr( |
| CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, |
| bool IsAddressOfOperand, const Scope *S, TypeSourceInfo **RecoveryTSI) { |
| DeclContext *DC = computeDeclContext(SS, false); |
| if (!DC) |
| return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(), |
| NameInfo, /*TemplateArgs=*/nullptr); |
| |
| if (RequireCompleteDeclContext(SS, DC)) |
| return ExprError(); |
| |
| LookupResult R(*this, NameInfo, LookupOrdinaryName); |
| LookupQualifiedName(R, DC); |
| |
| if (R.isAmbiguous()) |
| return ExprError(); |
| |
| if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation) |
| return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(), |
| NameInfo, /*TemplateArgs=*/nullptr); |
| |
| if (R.empty()) { |
| Diag(NameInfo.getLoc(), diag::err_no_member) |
| << NameInfo.getName() << DC << SS.getRange(); |
| return ExprError(); |
| } |
| |
| if (const TypeDecl *TD = R.getAsSingle<TypeDecl>()) { |
| // Diagnose a missing typename if this resolved unambiguously to a type in |
| // a dependent context. If we can recover with a type, downgrade this to |
| // a warning in Microsoft compatibility mode. |
| unsigned DiagID = diag::err_typename_missing; |
| if (RecoveryTSI && getLangOpts().MSVCCompat) |
| DiagID = diag::ext_typename_missing; |
| SourceLocation Loc = SS.getBeginLoc(); |
| auto D = Diag(Loc, DiagID); |
| D << SS.getScopeRep() << NameInfo.getName().getAsString() |
| << SourceRange(Loc, NameInfo.getEndLoc()); |
| |
| // Don't recover if the caller isn't expecting us to or if we're in a SFINAE |
| // context. |
| if (!RecoveryTSI) |
| return ExprError(); |
| |
| // Only issue the fixit if we're prepared to recover. |
| D << FixItHint::CreateInsertion(Loc, "typename "); |
| |
| // Recover by pretending this was an elaborated type. |
| QualType Ty = Context.getTypeDeclType(TD); |
| TypeLocBuilder TLB; |
| TLB.pushTypeSpec(Ty).setNameLoc(NameInfo.getLoc()); |
| |
| QualType ET = getElaboratedType(ETK_None, SS, Ty); |
| ElaboratedTypeLoc QTL = TLB.push<ElaboratedTypeLoc>(ET); |
| QTL.setElaboratedKeywordLoc(SourceLocation()); |
| QTL.setQualifierLoc(SS.getWithLocInContext(Context)); |
| |
| *RecoveryTSI = TLB.getTypeSourceInfo(Context, ET); |
| |
| return ExprEmpty(); |
| } |
| |
| // Defend against this resolving to an implicit member access. We usually |
| // won't get here if this might be a legitimate a class member (we end up in |
| // BuildMemberReferenceExpr instead), but this can be valid if we're forming |
| // a pointer-to-member or in an unevaluated context in C++11. |
| if (!R.empty() && (*R.begin())->isCXXClassMember() && !IsAddressOfOperand) |
| return BuildPossibleImplicitMemberExpr(SS, |
| /*TemplateKWLoc=*/SourceLocation(), |
| R, /*TemplateArgs=*/nullptr, S); |
| |
| return BuildDeclarationNameExpr(SS, R, /* ADL */ false); |
| } |
| |
| /// LookupInObjCMethod - The parser has read a name in, and Sema has |
| /// detected that we're currently inside an ObjC method. Perform some |
| /// additional lookup. |
| /// |
| /// Ideally, most of this would be done by lookup, but there's |
| /// actually quite a lot of extra work involved. |
| /// |
| /// Returns a null sentinel to indicate trivial success. |
| ExprResult |
| Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, |
| IdentifierInfo *II, bool AllowBuiltinCreation) { |
| SourceLocation Loc = Lookup.getNameLoc(); |
| ObjCMethodDecl *CurMethod = getCurMethodDecl(); |
| |
| // Check for error condition which is already reported. |
| if (!CurMethod) |
| return ExprError(); |
| |
| // There are two cases to handle here. 1) scoped lookup could have failed, |
| // in which case we should look for an ivar. 2) scoped lookup could have |
| // found a decl, but that decl is outside the current instance method (i.e. |
| // a global variable). In these two cases, we do a lookup for an ivar with |
| // this name, if the lookup sucedes, we replace it our current decl. |
| |
| // If we're in a class method, we don't normally want to look for |
| // ivars. But if we don't find anything else, and there's an |
| // ivar, that's an error. |
| bool IsClassMethod = CurMethod->isClassMethod(); |
| |
| bool LookForIvars; |
| if (Lookup.empty()) |
| LookForIvars = true; |
| else if (IsClassMethod) |
| LookForIvars = false; |
| else |
| LookForIvars = (Lookup.isSingleResult() && |
| Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod()); |
| ObjCInterfaceDecl *IFace = nullptr; |
| if (LookForIvars) { |
| IFace = CurMethod->getClassInterface(); |
| ObjCInterfaceDecl *ClassDeclared; |
| ObjCIvarDecl *IV = nullptr; |
| if (IFace && (IV = IFace->lookupInstanceVariable(II, ClassDeclared))) { |
| // Diagnose using an ivar in a class method. |
| if (IsClassMethod) |
| return ExprError(Diag(Loc, diag::err_ivar_use_in_class_method) |
| << IV->getDeclName()); |
| |
| // If we're referencing an invalid decl, just return this as a silent |
| // error node. The error diagnostic was already emitted on the decl. |
| if (IV->isInvalidDecl()) |
| return ExprError(); |
| |
| // Check if referencing a field with __attribute__((deprecated)). |
| if (DiagnoseUseOfDecl(IV, Loc)) |
| return ExprError(); |
| |
| // Diagnose the use of an ivar outside of the declaring class. |
| if (IV->getAccessControl() == ObjCIvarDecl::Private && |
| !declaresSameEntity(ClassDeclared, IFace) && |
| !getLangOpts().DebuggerSupport) |
| Diag(Loc, diag::err_private_ivar_access) << IV->getDeclName(); |
| |
| // FIXME: This should use a new expr for a direct reference, don't |
| // turn this into Self->ivar, just return a BareIVarExpr or something. |
| IdentifierInfo &II = Context.Idents.get("self"); |
| UnqualifiedId SelfName; |
| SelfName.setIdentifier(&II, SourceLocation()); |
| SelfName.setKind(UnqualifiedIdKind::IK_ImplicitSelfParam); |
| CXXScopeSpec SelfScopeSpec; |
| SourceLocation TemplateKWLoc; |
| ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, |
| SelfName, false, false); |
| if (SelfExpr.isInvalid()) |
| return ExprError(); |
| |
| SelfExpr = DefaultLvalueConversion(SelfExpr.get()); |
| if (SelfExpr.isInvalid()) |
| return ExprError(); |
| |
| MarkAnyDeclReferenced(Loc, IV, true); |
| |
| ObjCMethodFamily MF = CurMethod->getMethodFamily(); |
| if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize && |
| !IvarBacksCurrentMethodAccessor(IFace, CurMethod, IV)) |
| Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName(); |
| |
| ObjCIvarRefExpr *Result = new (Context) |
| ObjCIvarRefExpr(IV, IV->getUsageType(SelfExpr.get()->getType()), Loc, |
| IV->getLocation(), SelfExpr.get(), true, true); |
| |
| if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { |
| if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc)) |
| recordUseOfEvaluatedWeak(Result); |
| } |
| if (getLangOpts().ObjCAutoRefCount) { |
| if (CurContext->isClosure()) |
| Diag(Loc, diag::warn_implicitly_retains_self) |
| << FixItHint::CreateInsertion(Loc, "self->"); |
| } |
| |
| return Result; |
| } |
| } else if (CurMethod->isInstanceMethod()) { |
| // We should warn if a local variable hides an ivar. |
| if (ObjCInterfaceDecl *IFace = CurMethod->getClassInterface()) { |
| ObjCInterfaceDecl *ClassDeclared; |
| if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) { |
| if (IV->getAccessControl() != ObjCIvarDecl::Private || |
| declaresSameEntity(IFace, ClassDeclared)) |
| Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName(); |
| } |
| } |
| } else if (Lookup.isSingleResult() && |
| Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod()) { |
| // If accessing a stand-alone ivar in a class method, this is an error. |
| if (const ObjCIvarDecl *IV = dyn_cast<ObjCIvarDecl>(Lookup.getFoundDecl())) |
| return ExprError(Diag(Loc, diag::err_ivar_use_in_class_method) |
| << IV->getDeclName()); |
| } |
| |
| if (Lookup.empty() && II && AllowBuiltinCreation) { |
| // FIXME. Consolidate this with similar code in LookupName. |
| if (unsigned BuiltinID = II->getBuiltinID()) { |
| if (!(getLangOpts().CPlusPlus && |
| Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))) { |
| NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID, |
| S, Lookup.isForRedeclaration(), |
| Lookup.getNameLoc()); |
| if (D) Lookup.addDecl(D); |
| } |
| } |
| } |
| // Sentinel value saying that we didn't do anything special. |
| return ExprResult((Expr *)nullptr); |
| } |
| |
| /// \brief Cast a base object to a member's actual type. |
| /// |
| /// Logically this happens in three phases: |
| /// |
| /// * First we cast from the base type to the naming class. |
| /// The naming class is the class into which we were looking |
| /// when we found the member; it's the qualifier type if a |
| /// qualifier was provided, and otherwise it's the base type. |
| /// |
| /// * Next we cast from the naming class to the declaring class. |
| /// If the member we found was brought into a class's scope by |
| /// a using declaration, this is that class; otherwise it's |
| /// the class declaring the member. |
| /// |
| /// * Finally we cast from the declaring class to the "true" |
| /// declaring class of the member. This conversion does not |
| /// obey access control. |
| ExprResult |
| Sema::PerformObjectMemberConversion(Expr *From, |
| NestedNameSpecifier *Qualifier, |
| NamedDecl *FoundDecl, |
| NamedDecl *Member) { |
| CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Member->getDeclContext()); |
| if (!RD) |
| return From; |
| |
| QualType DestRecordType; |
| QualType DestType; |
| QualType FromRecordType; |
| QualType FromType = From->getType(); |
| bool PointerConversions = false; |
| if (isa<FieldDecl>(Member)) { |
| DestRecordType = Context.getCanonicalType(Context.getTypeDeclType(RD)); |
| |
| if (FromType->getAs<PointerType>()) { |
| DestType = Context.getPointerType(DestRecordType); |
| FromRecordType = FromType->getPointeeType(); |
| PointerConversions = true; |
| } else { |
| DestType = DestRecordType; |
| FromRecordType = FromType; |
| } |
| } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member)) { |
| if (Method->isStatic()) |
| return From; |
| |
| DestType = Method->getThisType(Context); |
| DestRecordType = DestType->getPointeeType(); |
| |
| if (FromType->getAs<PointerType>()) { |
| FromRecordType = FromType->getPointeeType(); |
| PointerConversions = true; |
| } else { |
| FromRecordType = FromType; |
| DestType = DestRecordType; |
| } |
| } else { |
| // No conversion necessary. |
| return From; |
| } |
| |
| if (DestType->isDependentType() || FromType->isDependentType()) |
| return From; |
| |
| // If the unqualified types are the same, no conversion is necessary. |
| if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType)) |
| return From; |
| |
| SourceRange FromRange = From->getSourceRange(); |
| SourceLocation FromLoc = FromRange.getBegin(); |
| |
| ExprValueKind VK = From->getValueKind(); |
| |
| // C++ [class.member.lookup]p8: |
| // [...] Ambiguities can often be resolved by qualifying a name with its |
| // class name. |
| // |
| // If the member was a qualified name and the qualified referred to a |
| // specific base subobject type, we'll cast to that intermediate type |
| // first and then to the object in which the member is declared. That allows |
| // one to resolve ambiguities in, e.g., a diamond-shaped hierarchy such as: |
| // |
| // class Base { public: int x; }; |
| // class Derived1 : public Base { }; |
| // class Derived2 : public Base { }; |
| // class VeryDerived : public Derived1, public Derived2 { void f(); }; |
| // |
| // void VeryDerived::f() { |
| // x = 17; // error: ambiguous base subobjects |
| // Derived1::x = 17; // okay, pick the Base subobject of Derived1 |
| // } |
| if (Qualifier && Qualifier->getAsType()) { |
| QualType QType = QualType(Qualifier->getAsType(), 0); |
| assert(QType->isRecordType() && "lookup done with non-record type"); |
| |
| QualType QRecordType = QualType(QType->getAs<RecordType>(), 0); |
| |
| // In C++98, the qualifier type doesn't actually have to be a base |
| // type of the object type, in which case we just ignore it. |
| // Otherwise build the appropriate casts. |
| if (IsDerivedFrom(FromLoc, FromRecordType, QRecordType)) { |
| CXXCastPath BasePath; |
| if (CheckDerivedToBaseConversion(FromRecordType, QRecordType, |
| FromLoc, FromRange, &BasePath)) |
| return ExprError(); |
| |
| if (PointerConversions) |
| QType = Context.getPointerType(QType); |
| From = ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase, |
| VK, &BasePath).get(); |
| |
| FromType = QType; |
| FromRecordType = QRecordType; |
| |
| // If the qualifier type was the same as the destination type, |
| // we're done. |
| if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType)) |
| return From; |
| } |
| } |
| |
| bool IgnoreAccess = false; |
| |
| // If we actually found the member through a using declaration, cast |
| // down to the using declaration's type. |
| // |
| // Pointer equality is fine here because only one declaration of a |
| // class ever has member declarations. |
| if (FoundDecl->getDeclContext() != Member->getDeclContext()) { |
| assert(isa<UsingShadowDecl>(FoundDecl)); |
| QualType URecordType = Context.getTypeDeclType( |
| cast<CXXRecordDecl>(FoundDecl->getDeclContext())); |
| |
| // We only need to do this if the naming-class to declaring-class |
| // conversion is non-trivial. |
| if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) { |
| assert(IsDerivedFrom(FromLoc, FromRecordType, URecordType)); |
| CXXCastPath BasePath; |
| if (CheckDerivedToBaseConversion(FromRecordType, URecordType, |
| FromLoc, FromRange, &BasePath)) |
| return ExprError(); |
| |
| QualType UType = URecordType; |
| if (PointerConversions) |
| UType = Context.getPointerType(UType); |
| From = ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase, |
| VK, &BasePath).get(); |
| FromType = UType; |
| FromRecordType = URecordType; |
| } |
| |
| // We don't do access control for the conversion from the |
| // declaring class to the true declaring class. |
| IgnoreAccess = true; |
| } |
| |
| CXXCastPath BasePath; |
| if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType, |
| FromLoc, FromRange, &BasePath, |
| IgnoreAccess)) |
| return ExprError(); |
| |
| return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, |
| VK, &BasePath); |
| } |
| |
| bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, |
| const LookupResult &R, |
| bool HasTrailingLParen) { |
| // Only when used directly as the postfix-expression of a call. |
| if (!HasTrailingLParen) |
| return false; |
| |
| // Never if a scope specifier was provided. |
| if (SS.isSet()) |
| return false; |
| |
| // Only in C++ or ObjC++. |
| if (!getLangOpts().CPlusPlus) |
| return false; |
| |
| // Turn off ADL when we find certain kinds of declarations during |
| // normal lookup: |
| for (NamedDecl *D : R) { |
| // C++0x [basic.lookup.argdep]p3: |
| // -- a declaration of a class member |
| // Since using decls preserve this property, we check this on the |
| // original decl. |
| if (D->isCXXClassMember()) |
| return false; |
| |
| // C++0x [basic.lookup.argdep]p3: |
| // -- a block-scope function declaration that is not a |
| // using-declaration |
| // NOTE: we also trigger this for function templates (in fact, we |
| // don't check the decl type at all, since all other decl types |
| // turn off ADL anyway). |
| if (isa<UsingShadowDecl>(D)) |
| D = cast<UsingShadowDecl>(D)->getTargetDecl(); |
| else if (D->getLexicalDeclContext()->isFunctionOrMethod()) |
| return false; |
| |
| // C++0x [basic.lookup.argdep]p3: |
| // -- a declaration that is neither a function or a function |
| // template |
| // And also for builtin functions. |
| if (isa<FunctionDecl>(D)) { |
| FunctionDecl *FDecl = cast<FunctionDecl>(D); |
| |
| // But also builtin functions. |
| if (FDecl->getBuiltinID() && FDecl->isImplicit()) |
| return false; |
| } else if (!isa<FunctionTemplateDecl>(D)) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| |
| /// Diagnoses obvious problems with the use of the given declaration |
| /// as an expression. This is only actually called for lookups that |
| /// were not overloaded, and it doesn't promise that the declaration |
| /// will in fact be used. |
| static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) { |
| if (D->isInvalidDecl()) |
| return true; |
| |
| if (isa<TypedefNameDecl>(D)) { |
| S.Diag(Loc, diag::err_unexpected_typedef) << D->getDeclName(); |
| return true; |
| } |
| |
| if (isa<ObjCInterfaceDecl>(D)) { |
| S.Diag(Loc, diag::err_unexpected_interface) << D->getDeclName(); |
| return true; |
| } |
| |
| if (isa<NamespaceDecl>(D)) { |
| S.Diag(Loc, diag::err_unexpected_namespace) << D->getDeclName(); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, |
| LookupResult &R, bool NeedsADL, |
| bool AcceptInvalidDecl) { |
| // If this is a single, fully-resolved result and we don't need ADL, |
| // just build an ordinary singleton decl ref. |
|