diff options
Diffstat (limited to 'include/clang/Sema/Sema.h')
-rw-r--r-- | include/clang/Sema/Sema.h | 914 |
1 files changed, 739 insertions, 175 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 437a44a30711..82caaeb24ae7 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -74,6 +74,7 @@ namespace clang { class ASTWriter; class ArrayType; class AttributeList; + class BindingDecl; class BlockDecl; class CapturedDecl; class CXXBasePath; @@ -454,9 +455,9 @@ public: /// \brief Store a list of either DeclRefExprs or MemberExprs /// that contain a reference to a variable (constant) that may or may not /// be odr-used in this Expr, and we won't know until all lvalue-to-rvalue - /// and discarded value conversions have been applied to all subexpressions - /// of the enclosing full expression. This is cleared at the end of each - /// full expression. + /// and discarded value conversions have been applied to all subexpressions + /// of the enclosing full expression. This is cleared at the end of each + /// full expression. llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs; /// \brief Stack containing information about each of the nested @@ -550,7 +551,8 @@ public: SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2> DelayedDefaultedMemberExceptionSpecs; - typedef llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> + typedef llvm::MapVector<const FunctionDecl *, + std::unique_ptr<LateParsedTemplate>> LateParsedTemplateMapT; LateParsedTemplateMapT LateParsedTemplateMap; @@ -669,15 +671,15 @@ public: class SynthesizedFunctionScope { Sema &S; Sema::ContextRAII SavedContext; - + public: SynthesizedFunctionScope(Sema &S, DeclContext *DC) - : S(S), SavedContext(S, DC) + : S(S), SavedContext(S, DC) { S.PushFunctionScope(); S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); } - + ~SynthesizedFunctionScope() { S.PopExpressionEvaluationContext(); S.PopFunctionScopeInfo(); @@ -720,6 +722,14 @@ public: /// standard library. LazyDeclPtr StdBadAlloc; + /// \brief The C++ "std::align_val_t" enum class, which is defined by the C++ + /// standard library. + LazyDeclPtr StdAlignValT; + + /// \brief The C++ "std::experimental" namespace, where the experimental parts + /// of the standard library resides. + NamespaceDecl *StdExperimentalNamespaceCache; + /// \brief The C++ "std::initializer_list" template, which is defined in /// \<initializer_list>. ClassTemplateDecl *StdInitializerList; @@ -778,15 +788,12 @@ public: /// \brief will hold 'respondsToSelector:' Selector RespondsToSelectorSel; - /// \brief counter for internal MS Asm label names. - unsigned MSAsmLabelNameCounter; - /// A flag to remember whether the implicit forms of operator new and delete /// have been declared. bool GlobalNewDeleteDeclared; /// A flag to indicate that we're in a context that permits abstract - /// references to fields. This is really a + /// references to fields. This is really a bool AllowAbstractFieldReference; /// \brief Describes how the expressions currently being parsed are @@ -866,7 +873,7 @@ public: /// /// This mangling information is allocated lazily, since most contexts /// do not have lambda expressions or block literals. - IntrusiveRefCntPtr<MangleNumberingContext> MangleNumbering; + std::unique_ptr<MangleNumberingContext> MangleNumbering; /// \brief If we are processing a decltype type, a set of call expressions /// for which we have deferred checking the completeness of the return type. @@ -1177,7 +1184,7 @@ public: /// is during Parsing. Currently it is used to pass on the depth /// when parsing generic lambda 'auto' parameters. void RecordParsingTemplateParameterDepth(unsigned Depth); - + void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, RecordDecl *RD, CapturedRegionKind K); @@ -1189,11 +1196,11 @@ public: sema::FunctionScopeInfo *getCurFunction() const { return FunctionScopes.back(); } - + sema::FunctionScopeInfo *getEnclosingFunction() const { if (FunctionScopes.empty()) return nullptr; - + for (int e = FunctionScopes.size()-1; e >= 0; --e) { if (isa<sema::BlockScopeInfo>(FunctionScopes[e])) continue; @@ -1201,13 +1208,13 @@ public: } return nullptr; } - + template <typename ExprT> void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) { if (!isUnevaluatedContext()) getCurFunction()->recordUseOfWeak(E, IsRead); } - + void PushCompoundScope(); void PopCompoundScope(); @@ -1293,7 +1300,9 @@ public: SourceLocation Loc, DeclarationName Entity); QualType BuildParenType(QualType T); QualType BuildAtomicType(QualType T, SourceLocation Loc); - QualType BuildPipeType(QualType T, + QualType BuildReadPipeType(QualType T, + SourceLocation Loc); + QualType BuildWritePipeType(QualType T, SourceLocation Loc); TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S); @@ -1321,18 +1330,20 @@ public: bool CheckEquivalentExceptionSpec( const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, const FunctionProtoType *Old, SourceLocation OldLoc, - const FunctionProtoType *New, SourceLocation NewLoc, - bool *MissingExceptionSpecification = nullptr, - bool *MissingEmptyExceptionSpecification = nullptr, - bool AllowNoexceptAllMatchWithNoSpec = false, - bool IsOperatorNew = false); - bool CheckExceptionSpecSubset( - const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, - const FunctionProtoType *Superset, SourceLocation SuperLoc, - const FunctionProtoType *Subset, SourceLocation SubLoc); - bool CheckParamExceptionSpec(const PartialDiagnostic & NoteID, - const FunctionProtoType *Target, SourceLocation TargetLoc, - const FunctionProtoType *Source, SourceLocation SourceLoc); + const FunctionProtoType *New, SourceLocation NewLoc); + bool CheckExceptionSpecSubset(const PartialDiagnostic &DiagID, + const PartialDiagnostic &NestedDiagID, + const PartialDiagnostic &NoteID, + const FunctionProtoType *Superset, + SourceLocation SuperLoc, + const FunctionProtoType *Subset, + SourceLocation SubLoc); + bool CheckParamExceptionSpec(const PartialDiagnostic &NestedDiagID, + const PartialDiagnostic &NoteID, + const FunctionProtoType *Target, + SourceLocation TargetLoc, + const FunctionProtoType *Source, + SourceLocation SourceLoc); TypeResult ActOnTypeName(Scope *S, Declarator &D); @@ -1393,8 +1404,14 @@ private: bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, TypeDiagnoser *Diagnoser); + struct ModuleScope { + clang::Module *Module; + VisibleModuleSet OuterVisibleModules; + }; + /// The modules we're currently parsing. + llvm::SmallVector<ModuleScope, 16> ModuleScopes; + VisibleModuleSet VisibleModules; - llvm::SmallVector<VisibleModuleSet, 16> VisibleModulesStack; Module *CachedFakeTopLevelModule; @@ -1510,12 +1527,6 @@ public: NamedDecl *Previous; }; - /// List of decls defined in a function prototype. This contains EnumConstants - /// that incorrectly end up in translation unit scope because there is no - /// function to pin them on. ActOnFunctionDeclarator reads this list and patches - /// them into the FunctionDecl. - std::vector<NamedDecl*> DeclsInPrototypeScope; - DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr); void DiagnoseUseOfUnimplementedSelectors(); @@ -1696,6 +1707,8 @@ public: /// to a shadowing declaration. void CheckShadowingDeclModification(Expr *E, SourceLocation Loc); + void DiagnoseShadowingLambdaDecls(const sema::LambdaScopeInfo *LSI); + private: /// Map of current shadowing declarations to shadowed declarations. Warn if /// it looks like the user is trying to modify the shadowing declaration. @@ -1716,11 +1729,16 @@ public: TypeSourceInfo *TInfo, LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists, - bool &AddToScope); + bool &AddToScope, + ArrayRef<BindingDecl *> Bindings = None); + NamedDecl * + ActOnDecompositionDeclarator(Scope *S, Declarator &D, + MultiTemplateParamsArg TemplateParamLists); // Returns true if the variable declaration is a redeclaration bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); void CheckVariableDeclarationType(VarDecl *NewVD); - void CheckCompleteVariableDeclaration(VarDecl *var); + void CheckCompleteVariableDeclaration(VarDecl *VD); + void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD); void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, @@ -1742,6 +1760,7 @@ public: bool CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, LookupResult &Previous, bool IsExplicitSpecialization); + bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl); void CheckMain(FunctionDecl *FD, const DeclSpec &D); void CheckMSVCRTEntryPoint(FunctionDecl *FD); Decl *ActOnParamDeclarator(Scope *S, Declarator &D); @@ -1766,6 +1785,8 @@ public: bool TypeMayContainAuto); void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto); void ActOnInitializerError(Decl *Dcl); + bool canInitializeWithParenthesizedList(QualType TargetType); + void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc); void ActOnCXXForRangeDecl(Decl *D); StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, @@ -1850,6 +1871,17 @@ public: AttributeList *AttrList, SourceLocation SemiLoc); + enum class ModuleDeclKind { + Module, ///< 'module X;' + Partition, ///< 'module partition X;' + Implementation, ///< 'module implementation X;' + }; + + /// The parser has processed a module-declaration that begins the definition + /// of a module interface or implementation. + DeclGroupPtrTy ActOnModuleDecl(SourceLocation ModuleLoc, ModuleDeclKind MDK, + ModuleIdPath Path); + /// \brief The parser has processed a module import declaration. /// /// \param AtLoc The location of the '@' symbol, if any. @@ -1863,16 +1895,13 @@ public: /// \brief The parser has processed a module import translated from a /// #include or similar preprocessing directive. void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod); + void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod); /// \brief The parsed has entered a submodule. void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod); /// \brief The parser has left a submodule. void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod); - /// \brief Check if module import may be found in the current context, - /// emit error if not. - void diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc); - /// \brief Create an implicit import of the given module at the given /// source location, for error recovery, if possible. /// @@ -1900,6 +1929,11 @@ public: SourceLocation DeclLoc, ArrayRef<Module *> Modules, MissingImportKind MIK, bool Recover); + Decl *ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, + SourceLocation LBraceLoc); + Decl *ActOnFinishExportDecl(Scope *S, Decl *ExportDecl, + SourceLocation RBraceLoc); + /// \brief We've found a use of a templated declaration that would trigger an /// implicit instantiation. Check that any relevant explicit specializations /// and partial specializations are visible, and diagnose if not. @@ -1939,6 +1973,24 @@ public: Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, RecordDecl *Record); + /// Common ways to introduce type names without a tag for use in diagnostics. + /// Keep in sync with err_tag_reference_non_tag. + enum NonTagKind { + NTK_NonStruct, + NTK_NonClass, + NTK_NonUnion, + NTK_NonEnum, + NTK_Typedef, + NTK_TypeAlias, + NTK_Template, + NTK_TypeAliasTemplate, + NTK_TemplateTemplateArgument, + }; + + /// Given a non-tag type declaration, returns an enum useful for indicating + /// what kind of non-tag type this is. + NonTagKind getNonTagTypeDeclKind(const Decl *D, TagTypeKind TTK); + bool isAcceptableTagRedeclaration(const TagDecl *Previous, TagTypeKind NewTag, bool isDefinition, SourceLocation NewTagLoc, @@ -2181,6 +2233,8 @@ public: VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range, VisibilityAttr::VisibilityType Vis, unsigned AttrSpellingListIndex); + UuidAttr *mergeUuidAttr(Decl *D, SourceRange Range, + unsigned AttrSpellingListIndex, StringRef Uuid); DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range, unsigned AttrSpellingListIndex); DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range, @@ -2219,6 +2273,7 @@ public: void MergeVarDecl(VarDecl *New, LookupResult &Previous); void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld); void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old); + bool checkVarDeclRedefinition(VarDecl *OldDefn, VarDecl *NewDefn); bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S); // AssignmentAction - This is used by all the assignment diagnostic functions @@ -2305,7 +2360,7 @@ public: bool IgnoreBaseAccess); bool IsQualificationConversion(QualType FromType, QualType ToType, bool CStyle, bool &ObjCLifetimeConversion); - bool IsNoReturnConversion(QualType FromType, QualType ToType, + bool IsFunctionConversion(QualType FromType, QualType ToType, QualType &ResultTy); bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType); bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg); @@ -2519,7 +2574,7 @@ public: OverloadCandidateSet& CandidateSet, SourceRange OpRange = SourceRange()); void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys, - ArrayRef<Expr *> Args, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool IsAssignmentOperator = false, unsigned NumContextualBoolArguments = 0); @@ -2799,8 +2854,8 @@ private: TypoDiagnosticGenerator DiagHandler; TypoRecoveryCallback RecoveryHandler; TypoExprState(); - TypoExprState(TypoExprState&& other) LLVM_NOEXCEPT; - TypoExprState& operator=(TypoExprState&& other) LLVM_NOEXCEPT; + TypoExprState(TypoExprState &&other) noexcept; + TypoExprState &operator=(TypoExprState &&other) noexcept; }; /// \brief The set of unhandled TypoExprs and their associated state. @@ -3015,7 +3070,7 @@ public: bool isValidPointerAttrType(QualType T, bool RefOkay = false); bool CheckRegparmAttr(const AttributeList &attr, unsigned &value); - bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, + bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, const FunctionDecl *FD = nullptr); bool CheckNoReturnAttr(const AttributeList &attr); bool checkStringLiteralArgumentAttr(const AttributeList &Attr, @@ -3059,10 +3114,14 @@ public: /// method) or an Objective-C property attribute, rather than as an /// underscored type specifier. /// + /// \param allowArrayTypes Whether to accept nullability specifiers on an + /// array type (e.g., because it will decay to a pointer). + /// /// \returns true if nullability cannot be applied, false otherwise. bool checkNullabilityTypeSpecifier(QualType &type, NullabilityKind nullability, SourceLocation nullabilityLoc, - bool isContextSensitive); + bool isContextSensitive, + bool allowArrayTypes); /// \brief Stmt attributes - this routine is the top level dispatcher. StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs, @@ -3117,18 +3176,18 @@ public: /// declared in class 'IFace'. bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV); - + /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which /// backs the property is not used in the property's accessor. void DiagnoseUnusedBackingIvarInAccessor(Scope *S, const ObjCImplementationDecl *ImplD); - + /// GetIvarBackingPropertyAccessor - If method is a property setter/getter and /// it property has a backing ivar, returns this ivar; otherwise, returns NULL. /// It also returns ivar's property on success. ObjCIvarDecl *GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, const ObjCPropertyDecl *&PDecl) const; - + /// Called by ActOnProperty to handle \@property declarations in /// class extensions. ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S, @@ -3228,12 +3287,12 @@ public: SmallVectorImpl<ObjCMethodDecl*>& Methods, bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound = nullptr); - + bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, bool receiverIdOrClass, SmallVectorImpl<ObjCMethodDecl*>& Methods); - + void DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, Selector Sel, SourceRange R, @@ -3245,7 +3304,7 @@ private: ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance, SmallVectorImpl<ObjCMethodDecl*>& Methods); - + /// \brief Record the typo correction failure and return an empty correction. TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc, @@ -3621,18 +3680,18 @@ public: void redelayDiagnostics(sema::DelayedDiagnosticPool &pool); - enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable, AD_Partial }; - - void EmitAvailabilityWarning(AvailabilityDiagnostic AD, - NamedDecl *D, StringRef Message, - SourceLocation Loc, + void EmitAvailabilityWarning(AvailabilityResult AR, NamedDecl *D, + StringRef Message, SourceLocation Loc, const ObjCInterfaceDecl *UnknownObjCClass, - const ObjCPropertyDecl *ObjCProperty, + const ObjCPropertyDecl *ObjCProperty, bool ObjCPropertyAccess); bool makeUnavailableInSystemHeader(SourceLocation loc, UnavailableAttr::ImplicitReason reason); + /// \brief Issue any -Wunguarded-availability warnings in \c FD + void DiagnoseUnguardedAvailabilityViolations(Decl *FD); + //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. @@ -3718,16 +3777,16 @@ public: /// /// \param FunctionScopeIndexToStopAt If non-null, it points to the index /// of the FunctionScopeInfo stack beyond which we do not attempt to capture. - /// This is useful when enclosing lambdas must speculatively capture + /// This is useful when enclosing lambdas must speculatively capture /// variables that may or may not be used in certain specializations of /// a nested generic lambda. - /// + /// /// \returns true if an error occurred (i.e., the variable cannot be /// captured) and false if the capture succeeded. bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, - QualType &DeclRefType, + QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt); /// \brief Try to capture the given variable. @@ -3965,6 +4024,12 @@ public: bool SuppressQualifierCheck = false, ActOnMemberAccessExtraArgs *ExtraArgs = nullptr); + ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, + SourceLocation OpLoc, + const CXXScopeSpec &SS, FieldDecl *Field, + DeclAccessPair FoundDecl, + const DeclarationNameInfo &MemberNameInfo); + ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow); bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType, @@ -4201,7 +4266,10 @@ public: NamespaceDecl *getStdNamespace() const; NamespaceDecl *getOrCreateStdNamespace(); + NamespaceDecl *lookupStdExperimentalNamespace(); + CXXRecordDecl *getStdBadAlloc() const; + EnumDecl *getStdAlignValT() const; /// \brief Tests whether Ty is an instance of std::initializer_list and, if /// it is and Element is not NULL, assigns the element type to Element. @@ -4249,18 +4317,22 @@ public: SourceLocation NameLoc, const LookupResult &Previous); bool CheckUsingDeclQualifier(SourceLocation UsingLoc, + bool HasTypename, const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, SourceLocation NameLoc); NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, + bool HasTypenameKeyword, + SourceLocation TypenameLoc, CXXScopeSpec &SS, DeclarationNameInfo NameInfo, + SourceLocation EllipsisLoc, AttributeList *AttrList, - bool IsInstantiation, - bool HasTypenameKeyword, - SourceLocation TypenameLoc); + bool IsInstantiation); + NamedDecl *BuildUsingPackDecl(NamedDecl *InstantiatedFrom, + ArrayRef<NamedDecl *> Expansions); bool CheckInheritingConstructorUsingDecl(UsingDecl *UD); @@ -4273,13 +4345,12 @@ public: Decl *ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, - bool HasUsingKeyword, SourceLocation UsingLoc, + SourceLocation TypenameLoc, CXXScopeSpec &SS, UnqualifiedId &Name, - AttributeList *AttrList, - bool HasTypenameKeyword, - SourceLocation TypenameLoc); + SourceLocation EllipsisLoc, + AttributeList *AttrList); Decl *ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS, MultiTemplateParamsArg TemplateParams, @@ -4326,6 +4397,12 @@ public: ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field); + + /// Instantiate or parse a C++ default argument expression as necessary. + /// Return true on error. + bool CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, + ParmVarDecl *Param); + /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating /// the default expr if needed. ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, @@ -4721,12 +4798,12 @@ public: /// /// \param FunctionScopeIndexToStopAt If non-null, it points to the index /// of the FunctionScopeInfo stack beyond which we do not attempt to capture. - /// This is useful when enclosing lambdas must speculatively capture + /// This is useful when enclosing lambdas must speculatively capture /// 'this' that may or may not be used in certain specializations of - /// a nested generic lambda (depending on whether the name resolves to + /// a nested generic lambda (depending on whether the name resolves to /// a non-static member function or a static function). /// \return returns 'true' if failed, 'false' if success. - bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, + bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, bool BuildAndDiagnose = true, const unsigned *const FunctionScopeIndexToStopAt = nullptr, bool ByCopy = false); @@ -4793,25 +4870,22 @@ public: SourceRange R); bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, bool UseGlobal, QualType AllocType, bool IsArray, - MultiExprArg PlaceArgs, + bool &PassAlignment, MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete); - bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, - DeclarationName Name, MultiExprArg Args, - DeclContext *Ctx, - bool AllowMissing, FunctionDecl *&Operator, - bool Diagnose = true); void DeclareGlobalNewDelete(); void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, - QualType Param1, - QualType Param2 = QualType()); + ArrayRef<QualType> Params); bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl* &Operator, bool Diagnose = true); FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc, bool CanProvideSize, + bool Overaligned, DeclarationName Name); + FunctionDecl *FindDeallocationFunctionForDestructor(SourceLocation StartLoc, + CXXRecordDecl *RD); /// ActOnCXXDelete - Parsed a C++ 'delete' expression ExprResult ActOnCXXDelete(SourceLocation StartLoc, @@ -4949,16 +5023,41 @@ public: bool *CanCorrect = nullptr); NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS); + /// \brief Keeps information about an identifier in a nested-name-spec. + /// + struct NestedNameSpecInfo { + /// \brief The type of the object, if we're parsing nested-name-specifier in + /// a member access expression. + ParsedType ObjectType; + + /// \brief The identifier preceding the '::'. + IdentifierInfo *Identifier; + + /// \brief The location of the identifier. + SourceLocation IdentifierLoc; + + /// \brief The location of the '::'. + SourceLocation CCLoc; + + /// \brief Creates info object for the most typical case. + NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc, + SourceLocation ColonColonLoc, ParsedType ObjectType = ParsedType()) + : ObjectType(ObjectType), Identifier(II), IdentifierLoc(IdLoc), + CCLoc(ColonColonLoc) { + } + + NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc, + SourceLocation ColonColonLoc, QualType ObjectType) + : ObjectType(ParsedType::make(ObjectType)), Identifier(II), + IdentifierLoc(IdLoc), CCLoc(ColonColonLoc) { + } + }; + bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS, - SourceLocation IdLoc, - IdentifierInfo &II, - ParsedType ObjectType); + NestedNameSpecInfo &IdInfo); bool BuildCXXNestedNameSpecifier(Scope *S, - IdentifierInfo &Identifier, - SourceLocation IdentifierLoc, - SourceLocation CCLoc, - QualType ObjectType, + NestedNameSpecInfo &IdInfo, bool EnteringContext, CXXScopeSpec &SS, NamedDecl *ScopeLookupResult, @@ -4969,14 +5068,8 @@ public: /// /// \param S The scope in which this nested-name-specifier occurs. /// - /// \param Identifier The identifier preceding the '::'. - /// - /// \param IdentifierLoc The location of the identifier. - /// - /// \param CCLoc The location of the '::'. - /// - /// \param ObjectType The type of the object, if we're parsing - /// nested-name-specifier in a member access expression. + /// \param IdInfo Parser information about an identifier in the + /// nested-name-spec. /// /// \param EnteringContext Whether we're entering the context nominated by /// this nested-name-specifier. @@ -4995,10 +5088,7 @@ public: /// /// \returns true if an error occurred, false otherwise. bool ActOnCXXNestedNameSpecifier(Scope *S, - IdentifierInfo &Identifier, - SourceLocation IdentifierLoc, - SourceLocation CCLoc, - ParsedType ObjectType, + NestedNameSpecInfo &IdInfo, bool EnteringContext, CXXScopeSpec &SS, bool ErrorRecoveryLookup = false, @@ -5011,10 +5101,7 @@ public: SourceLocation ColonColonLoc); bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, - IdentifierInfo &Identifier, - SourceLocation IdentifierLoc, - SourceLocation ColonLoc, - ParsedType ObjectType, + NestedNameSpecInfo &IdInfo, bool EnteringContext); /// \brief The parser has parsed a nested-name-specifier @@ -5106,7 +5193,7 @@ public: /// \brief Create a new lambda closure type. CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange, TypeSourceInfo *Info, - bool KnownDependent, + bool KnownDependent, LambdaCaptureDefault CaptureDefault); /// \brief Start the definition of a lambda expression. @@ -5114,10 +5201,11 @@ public: SourceRange IntroducerRange, TypeSourceInfo *MethodType, SourceLocation EndLoc, - ArrayRef<ParmVarDecl *> Params); + ArrayRef<ParmVarDecl *> Params, + bool IsConstexprSpecified); /// \brief Endow the lambda scope info with the relevant properties. - void buildLambdaScope(sema::LambdaScopeInfo *LSI, + void buildLambdaScope(sema::LambdaScopeInfo *LSI, CXXMethodDecl *CallOperator, SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault, @@ -5141,7 +5229,7 @@ public: /// \brief Create a dummy variable within the declcontext of the lambda's /// call operator, for name lookup purposes for a lambda init capture. - /// + /// /// CodeGen handles emission of lambda captures, ignoring these dummy /// variables appropriately. VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc, @@ -5540,7 +5628,7 @@ public: /// CheckOverrideControl - Check C++11 override control semantics. void CheckOverrideControl(NamedDecl *D); - + /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was /// not used in the declaration of an overriding method. void DiagnoseAbsenceOfOverrideControl(NamedDecl *D); @@ -5682,6 +5770,14 @@ public: TemplateTy &SuggestedTemplate, TemplateNameKind &SuggestedKind); + bool DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation, + NamedDecl *Instantiation, + bool InstantiatedFromMember, + const NamedDecl *Pattern, + const NamedDecl *PatternDef, + TemplateSpecializationKind TSK, + bool Complain = true); + void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl); TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl); @@ -5694,7 +5790,10 @@ public: SourceLocation EqualLoc, ParsedType DefaultArg); + QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, + SourceLocation Loc); QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc); + Decl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, unsigned Depth, unsigned Position, @@ -5753,6 +5852,10 @@ public: TemplateParameterList **OuterTemplateParamLists, SkipBodyInfo *SkipBody = nullptr); + TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, + QualType NTTPType, + SourceLocation Loc); + void translateTemplateArguments(const ASTTemplateArgsPtr &In, TemplateArgumentListInfo &Out); @@ -5827,6 +5930,15 @@ public: MultiTemplateParamsArg TemplateParameterLists, SkipBodyInfo *SkipBody = nullptr); + bool CheckTemplatePartialSpecializationArgs(SourceLocation Loc, + TemplateDecl *PrimaryTemplate, + unsigned NumExplicitArgs, + ArrayRef<TemplateArgument> Args); + void CheckTemplatePartialSpecialization( + ClassTemplatePartialSpecializationDecl *Partial); + void CheckTemplatePartialSpecialization( + VarTemplatePartialSpecializationDecl *Partial); + Decl *ActOnTemplateDeclarator(Scope *S, MultiTemplateParamsArg TemplateParameterLists, Declarator &D); @@ -6253,9 +6365,9 @@ public: /// \brief Collect the set of unexpanded parameter packs within the given /// nested-name-specifier. /// - /// \param SS The nested-name-specifier that will be traversed to find + /// \param NNS The nested-name-specifier that will be traversed to find /// unexpanded parameter packs. - void collectUnexpandedParameterPacks(CXXScopeSpec &SS, + void collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS, SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); /// \brief Collect the set of unexpanded parameter packs within the given @@ -6399,11 +6511,24 @@ public: SourceLocation &Ellipsis, Optional<unsigned> &NumExpansions) const; + /// Given a template argument that contains an unexpanded parameter pack, but + /// which has already been substituted, attempt to determine the number of + /// elements that will be produced once this argument is fully-expanded. + /// + /// This is intended for use when transforming 'sizeof...(Arg)' in order to + /// avoid actually expanding the pack where possible. + Optional<unsigned> getFullyPackExpandedSize(TemplateArgument Arg); + //===--------------------------------------------------------------------===// // C++ Template Argument Deduction (C++ [temp.deduct]) //===--------------------------------------------------------------------===// - QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType); + /// Adjust the type \p ArgFunctionType to match the calling convention, + /// noreturn, and optionally the exception specification of \p FunctionType. + /// Deduction often wants to ignore these properties when matching function + /// types. + QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType, + bool AdjustExceptionSpec = false); /// \brief Describes the result of template argument deduction. /// @@ -6455,7 +6580,9 @@ public: /// not be resolved to a suitable function. TDK_FailedOverloadResolution, /// \brief Deduction failed; that's all we know. - TDK_MiscellaneousDeductionFailure + TDK_MiscellaneousDeductionFailure, + /// \brief CUDA Target attributes do not match. + TDK_CUDATargetMismatch }; TemplateDeductionResult @@ -6512,7 +6639,7 @@ public: QualType ArgFunctionType, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, - bool InOverloadResolution = false); + bool IsAddressOfFunction = false); TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, @@ -6525,12 +6652,12 @@ public: TemplateArgumentListInfo *ExplicitTemplateArgs, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, - bool InOverloadResolution = false); + bool IsAddressOfFunction = false); /// \brief Substitute Replacement for \p auto in \p TypeWithAuto QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement); /// \brief Substitute Replacement for auto in TypeWithAuto - TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, + TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement); /// \brief Result type of DeduceAutoType. @@ -6540,10 +6667,12 @@ public: DAR_FailedAlreadyDiagnosed }; - DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, - QualType &Result); - DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, - QualType &Result); + DeduceAutoResult + DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result, + Optional<unsigned> DependentDeductionDepth = None); + DeduceAutoResult + DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result, + Optional<unsigned> DependentDeductionDepth = None); void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init); bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose = true); @@ -6580,10 +6709,19 @@ public: ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc); + bool isMoreSpecializedThanPrimary(ClassTemplatePartialSpecializationDecl *T, + sema::TemplateDeductionInfo &Info); + VarTemplatePartialSpecializationDecl *getMoreSpecializedPartialSpecialization( VarTemplatePartialSpecializationDecl *PS1, VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc); + bool isMoreSpecializedThanPrimary(VarTemplatePartialSpecializationDecl *T, + sema::TemplateDeductionInfo &Info); + + bool isTemplateTemplateParameterAtLeastAsSpecializedAs( + TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc); + void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs, bool OnlyDeduced, unsigned Depth, @@ -6634,8 +6772,8 @@ public: /// We are substituting template argument determined as part of /// template argument deduction for either a class template /// partial specialization or a function template. The - /// Entity is either a ClassTemplatePartialSpecializationDecl or - /// a FunctionTemplateDecl. + /// Entity is either a {Class|Var}TemplatePartialSpecializationDecl or + /// a TemplateDecl. DeducedTemplateArgumentSubstitution, /// We are substituting prior template arguments into a new @@ -6857,6 +6995,14 @@ public: SourceRange InstantiationRange = SourceRange()); /// \brief Note that we are instantiating as part of template + /// argument deduction for a class template declaration. + InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + TemplateDecl *Template, + ArrayRef<TemplateArgument> TemplateArgs, + sema::TemplateDeductionInfo &DeductionInfo, + SourceRange InstantiationRange = SourceRange()); + + /// \brief Note that we are instantiating as part of template /// argument deduction for a class template partial /// specialization. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, @@ -7118,7 +7264,7 @@ public: public: /// Set the ExtParameterInfo for the parameter at the given index, - /// + /// void set(unsigned index, FunctionProtoType::ExtParameterInfo info) { assert(Infos.size() <= index); Infos.resize(index); @@ -7357,7 +7503,7 @@ public: const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList); - + void ActOnSuperClassOfClassInterface(Scope *S, SourceLocation AtInterfaceLoc, ObjCInterfaceDecl *IDecl, @@ -7367,8 +7513,9 @@ public: SourceLocation SuperLoc, ArrayRef<ParsedType> SuperTypeArgs, SourceRange SuperTypeArgsRange); - + void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs, + SmallVectorImpl<SourceLocation> &ProtocolLocs, IdentifierInfo *SuperName, SourceLocation SuperLoc); @@ -7475,6 +7622,14 @@ public: ArrayRef<SourceLocation> ProtocolLocs, SourceLocation ProtocolRAngleLoc); + /// Build an Objective-C type parameter type. + QualType BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, + SourceLocation ProtocolLAngleLoc, + ArrayRef<ObjCProtocolDecl *> Protocols, + ArrayRef<SourceLocation> ProtocolLocs, + SourceLocation ProtocolRAngleLoc, + bool FailOnError = false); + /// Build an Objective-C object pointer type. QualType BuildObjCObjectType(QualType BaseType, SourceLocation Loc, @@ -7685,14 +7840,14 @@ public: ParsedType Type, SourceLocation RParenLoc, Expr *SubExpr); - + void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr); - + void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr); - + bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind); - + bool checkObjCBridgeRelatedComponents(SourceLocation Loc, QualType DestType, QualType SrcType, ObjCInterfaceDecl *&RelatedClass, @@ -7932,6 +8087,58 @@ public: void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body); //===--------------------------------------------------------------------===// + // OpenCL extensions. + // +private: + std::string CurrOpenCLExtension; + /// Extensions required by an OpenCL type. + llvm::DenseMap<const Type*, std::set<std::string>> OpenCLTypeExtMap; + /// Extensions required by an OpenCL declaration. + llvm::DenseMap<const Decl*, std::set<std::string>> OpenCLDeclExtMap; +public: + llvm::StringRef getCurrentOpenCLExtension() const { + return CurrOpenCLExtension; + } + void setCurrentOpenCLExtension(llvm::StringRef Ext) { + CurrOpenCLExtension = Ext; + } + + /// \brief Set OpenCL extensions for a type which can only be used when these + /// OpenCL extensions are enabled. If \p Exts is empty, do nothing. + /// \param Exts A space separated list of OpenCL extensions. + void setOpenCLExtensionForType(QualType T, llvm::StringRef Exts); + + /// \brief Set OpenCL extensions for a declaration which can only be + /// used when these OpenCL extensions are enabled. If \p Exts is empty, do + /// nothing. + /// \param Exts A space separated list of OpenCL extensions. + void setOpenCLExtensionForDecl(Decl *FD, llvm::StringRef Exts); + + /// \brief Set current OpenCL extensions for a type which can only be used + /// when these OpenCL extensions are enabled. If current OpenCL extension is + /// empty, do nothing. + void setCurrentOpenCLExtensionForType(QualType T); + + /// \brief Set current OpenCL extensions for a declaration which + /// can only be used when these OpenCL extensions are enabled. If current + /// OpenCL extension is empty, do nothing. + void setCurrentOpenCLExtensionForDecl(Decl *FD); + + bool isOpenCLDisabledDecl(Decl *FD); + + /// \brief Check if type \p T corresponding to declaration specifier \p DS + /// is disabled due to required OpenCL extensions being disabled. If so, + /// emit diagnostics. + /// \return true if type is disabled. + bool checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType T); + + /// \brief Check if declaration \p D used by expression \p E + /// is disabled due to required OpenCL extensions being disabled. If so, + /// emit diagnostics. + /// \return true if type is disabled. + bool checkOpenCLDisabledDecl(const Decl &D, const Expr &E); + + //===--------------------------------------------------------------------===// // OpenMP directives and clauses. // private: @@ -7947,6 +8154,21 @@ private: /// Returns OpenMP nesting level for current directive. unsigned getOpenMPNestingLevel() const; + /// Checks if a type or a declaration is disabled due to the owning extension + /// being disabled, and emits diagnostic messages if it is disabled. + /// \param D type or declaration to be checked. + /// \param DiagLoc source location for the diagnostic message. + /// \param DiagInfo information to be emitted for the diagnostic message. + /// \param SrcRange source range of the declaration. + /// \param Map maps type or declaration to the extensions. + /// \param Selector selects diagnostic message: 0 for type and 1 for + /// declaration. + /// \return true if the type or declaration is disabled. + template <typename T, typename DiagLocT, typename DiagInfoT, typename MapT> + bool checkOpenCLDisabledTypeOrDecl(T D, DiagLocT DiagLoc, DiagInfoT DiagInfo, + MapT &Map, unsigned Selector = 0, + SourceRange SrcRange = SourceRange()); + public: /// \brief Return true if the provided declaration \a VD should be captured by /// reference. @@ -8244,6 +8466,54 @@ public: ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp target simd' after parsing of + /// the associated statement. + StmtResult ActOnOpenMPTargetSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// Called on well-formed '\#pragma omp teams distribute' after parsing of + /// the associated statement. + StmtResult ActOnOpenMPTeamsDistributeDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// Called on well-formed '\#pragma omp teams distribute simd' after parsing + /// of the associated statement. + StmtResult ActOnOpenMPTeamsDistributeSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// Called on well-formed '\#pragma omp teams distribute parallel for simd' + /// after parsing of the associated statement. + StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// Called on well-formed '\#pragma omp teams distribute parallel for' + /// after parsing of the associated statement. + StmtResult ActOnOpenMPTeamsDistributeParallelForDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// Called on well-formed '\#pragma omp target teams' after parsing of the + /// associated statement. + StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// Called on well-formed '\#pragma omp target teams distribute' after parsing + /// of the associated statement. + StmtResult ActOnOpenMPTargetTeamsDistributeDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// Called on well-formed '\#pragma omp target teams distribute parallel for' + /// after parsing of the associated statement. + StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// Checks correctness of linear modifiers. bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, @@ -8565,6 +8835,11 @@ public: // argument, and arguments that have type float are promoted to double. ExprResult DefaultArgumentPromotion(Expr *E); + /// If \p E is a prvalue denoting an unmaterialized temporary, materialize + /// it as an xvalue. In C++98, the result will still be a prvalue, because + /// we don't have xvalues there. + ExprResult TemporaryMaterializationConversion(Expr *E); + // Used for emitting the right warning by DefaultVariadicArgumentPromotion enum VariadicCallType { VariadicFunction, @@ -8646,8 +8921,8 @@ public: /// are not compatible, but we accept them as an extension. IncompatiblePointer, - /// IncompatiblePointer - The assignment is between two pointers types which - /// point to integers which have a different sign, but are otherwise + /// IncompatiblePointerSign - The assignment is between two pointers types + /// which point to integers which have a different sign, but are otherwise /// identical. This is a subset of the above, but broken out because it's by /// far the most common case of incompatible pointers. IncompatiblePointerSign, @@ -8728,15 +9003,23 @@ public: CastKind &Kind, bool ConvertRHS = true); - // CheckSingleAssignmentConstraints - Currently used by - // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking, - // this routine performs the default function/array converions, if ConvertRHS - // is true. - AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, - ExprResult &RHS, - bool Diagnose = true, - bool DiagnoseCFAudited = false, - bool ConvertRHS = true); + /// Check assignment constraints for an assignment of RHS to LHSType. + /// + /// \param LHSType The destination type for the assignment. + /// \param RHS The source expression for the assignment. + /// \param Diagnose If \c true, diagnostics may be produced when checking + /// for assignability. If a diagnostic is produced, \p RHS will be + /// set to ExprError(). Note that this function may still return + /// without producing a diagnostic, even for an invalid assignment. + /// \param DiagnoseCFAudited If \c true, the target is a function parameter + /// in an audited Core Foundation API and does not need to be checked + /// for ARC retain issues. + /// \param ConvertRHS If \c true, \p RHS will be updated to model the + /// conversions necessary to perform the assignment. If \c false, + /// \p Diagnose must also be \c false. + AssignConvertType CheckSingleAssignmentConstraints( + QualType LHSType, ExprResult &RHS, bool Diagnose = true, + bool DiagnoseCFAudited = false, bool ConvertRHS = true); // \brief If the lhs type is a transparent union, check whether we // can initialize the transparent union with the given expression. @@ -8792,8 +9075,8 @@ public: ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, BinaryOperatorKind Opc, bool isRelational); QualType CheckBitwiseOperands( // C99 6.5.[10...12] - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, - bool IsCompAssign = false); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, + BinaryOperatorKind Opc); QualType CheckLogicalOperands( // C99 6.5.[13,14] ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, BinaryOperatorKind Opc); @@ -8818,13 +9101,13 @@ public: ExprResult &cond, ExprResult &lhs, ExprResult &rhs, ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc); QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2, - bool *NonStandardCompositeType = nullptr); + bool ConvertArgs = true); QualType FindCompositePointerType(SourceLocation Loc, ExprResult &E1, ExprResult &E2, - bool *NonStandardCompositeType = nullptr) { + bool ConvertArgs = true) { Expr *E1Tmp = E1.get(), *E2Tmp = E2.get(); - QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp, - NonStandardCompositeType); + QualType Composite = + FindCompositePointerType(Loc, E1Tmp, E2Tmp, ConvertArgs); E1 = E1Tmp; E2 = E2Tmp; return Composite; @@ -8869,13 +9152,7 @@ public: /// that their unqualified forms (T1 and T2) are either the same /// or T1 is a base class of T2. Ref_Related, - /// Ref_Compatible_With_Added_Qualification - The two types are - /// reference-compatible with added qualification, meaning that - /// they are reference-compatible and the qualifiers on T1 (cv1) - /// are greater than the qualifiers on T2 (cv2). - Ref_Compatible_With_Added_Qualification, - /// Ref_Compatible - The two types are reference-compatible and - /// have equivalent qualifiers (cv1 == cv2). + /// Ref_Compatible - The two types are reference-compatible. Ref_Compatible }; @@ -9104,6 +9381,154 @@ public: QualType FieldTy, bool IsMsStruct, Expr *BitWidth, bool *ZeroWidth = nullptr); +private: + unsigned ForceCUDAHostDeviceDepth = 0; + +public: + /// Increments our count of the number of times we've seen a pragma forcing + /// functions to be __host__ __device__. So long as this count is greater + /// than zero, all functions encountered will be __host__ __device__. + void PushForceCUDAHostDevice(); + + /// Decrements our count of the number of times we've seen a pragma forcing + /// functions to be __host__ __device__. Returns false if the count is 0 + /// before incrementing, so you can emit an error. + bool PopForceCUDAHostDevice(); + + /// Diagnostics that are emitted only if we discover that the given function + /// must be codegen'ed. Because handling these correctly adds overhead to + /// compilation, this is currently only enabled for CUDA compilations. + llvm::DenseMap<CanonicalDeclPtr<FunctionDecl>, + std::vector<PartialDiagnosticAt>> + CUDADeferredDiags; + + /// A pair of a canonical FunctionDecl and a SourceLocation. When used as the + /// key in a hashtable, both the FD and location are hashed. + struct FunctionDeclAndLoc { + CanonicalDeclPtr<FunctionDecl> FD; + SourceLocation Loc; + }; + + /// FunctionDecls and SourceLocations for which CheckCUDACall has emitted a + /// (maybe deferred) "bad call" diagnostic. We use this to avoid emitting the + /// same deferred diag twice. + llvm::DenseSet<FunctionDeclAndLoc> LocsWithCUDACallDiags; + + /// An inverse call graph, mapping known-emitted functions to one of their + /// known-emitted callers (plus the location of the call). + /// + /// Functions that we can tell a priori must be emitted aren't added to this + /// map. + llvm::DenseMap</* Callee = */ CanonicalDeclPtr<FunctionDecl>, + /* Caller = */ FunctionDeclAndLoc> + CUDAKnownEmittedFns; + + /// A partial call graph maintained during CUDA compilation to support + /// deferred diagnostics. + /// + /// Functions are only added here if, at the time they're considered, they are + /// not known-emitted. As soon as we discover that a function is + /// known-emitted, we remove it and everything it transitively calls from this + /// set and add those functions to CUDAKnownEmittedFns. + llvm::DenseMap</* Caller = */ CanonicalDeclPtr<FunctionDecl>, + /* Callees = */ llvm::MapVector<CanonicalDeclPtr<FunctionDecl>, + SourceLocation>> + CUDACallGraph; + + /// Diagnostic builder for CUDA errors which may or may not be deferred. + /// + /// In CUDA, there exist constructs (e.g. variable-length arrays, try/catch) + /// which are not allowed to appear inside __device__ functions and are + /// allowed to appear in __host__ __device__ functions only if the host+device + /// function is never codegen'ed. + /// + /// To handle this, we use the notion of "deferred diagnostics", where we + /// attach a diagnostic to a FunctionDecl that's emitted iff it's codegen'ed. + /// + /// This class lets you emit either a regular diagnostic, a deferred + /// diagnostic, or no diagnostic at all, according to an argument you pass to + /// its constructor, thus simplifying the process of creating these "maybe + /// deferred" diagnostics. + class CUDADiagBuilder { + public: + enum Kind { + /// Emit no diagnostics. + K_Nop, + /// Emit the diagnostic immediately (i.e., behave like Sema::Diag()). + K_Immediate, + /// Emit the diagnostic immediately, and, if it's a warning or error, also + /// emit a call stack showing how this function can be reached by an a + /// priori known-emitted function. + K_ImmediateWithCallStack, + /// Create a deferred diagnostic, which is emitted only if the function + /// it's attached to is codegen'ed. Also emit a call stack as with + /// K_ImmediateWithCallStack. + K_Deferred + }; + + CUDADiagBuilder(Kind K, SourceLocation Loc, unsigned DiagID, + FunctionDecl *Fn, Sema &S); + ~CUDADiagBuilder(); + + /// Convertible to bool: True if we immediately emitted an error, false if + /// we didn't emit an error or we created a deferred error. + /// + /// Example usage: + /// + /// if (CUDADiagBuilder(...) << foo << bar) + /// return ExprError(); + /// + /// But see CUDADiagIfDeviceCode() and CUDADiagIfHostCode() -- you probably + /// want to use these instead of creating a CUDADiagBuilder yourself. + operator bool() const { return ImmediateDiag.hasValue(); } + + template <typename T> + friend const CUDADiagBuilder &operator<<(const CUDADiagBuilder &Diag, + const T &Value) { + if (Diag.ImmediateDiag.hasValue()) + *Diag.ImmediateDiag << Value; + else if (Diag.PartialDiag.hasValue()) + *Diag.PartialDiag << Value; + return Diag; + } + + private: + Sema &S; + SourceLocation Loc; + unsigned DiagID; + FunctionDecl *Fn; + bool ShowCallStack; + + // Invariant: At most one of these Optionals has a value. + // FIXME: Switch these to a Variant once that exists. + llvm::Optional<SemaDiagnosticBuilder> ImmediateDiag; + llvm::Optional<PartialDiagnostic> PartialDiag; + }; + + /// Creates a CUDADiagBuilder that emits the diagnostic if the current context + /// is "used as device code". + /// + /// - If CurContext is a __host__ function, does not emit any diagnostics. + /// - If CurContext is a __device__ or __global__ function, emits the + /// diagnostics immediately. + /// - If CurContext is a __host__ __device__ function and we are compiling for + /// the device, creates a diagnostic which is emitted if and when we realize + /// that the function will be codegen'ed. + /// + /// Example usage: + /// + /// // Variable-length arrays are not allowed in CUDA device code. + /// if (CUDADiagIfDeviceCode(Loc, diag::err_cuda_vla) << CurrentCUDATarget()) + /// return ExprError(); + /// // Otherwise, continue parsing as normal. + CUDADiagBuilder CUDADiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); + + /// Creates a CUDADiagBuilder that emits the diagnostic if the current context + /// is "used as host code". + /// + /// Same as CUDADiagIfDeviceCode, with "host" and "device" switched. + CUDADiagBuilder CUDADiagIfHostCode(SourceLocation Loc, unsigned DiagID); + enum CUDAFunctionTarget { CFT_Device, CFT_Global, @@ -9112,7 +9537,19 @@ public: CFT_InvalidTarget }; - CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D); + /// Determines whether the given function is a CUDA device/host/kernel/etc. + /// function. + /// + /// Use this rather than examining the function's attributes yourself -- you + /// will get it wrong. Returns CFT_Host if D is null. + CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D, + bool IgnoreImplicitHDAttr = false); + CUDAFunctionTarget IdentifyCUDATarget(const AttributeList *Attr); + + /// Gets the CUDA target for the current context. + CUDAFunctionTarget CurrentCUDATarget() { + return IdentifyCUDATarget(dyn_cast<FunctionDecl>(CurContext)); + } // CUDA function call preference. Must be ordered numerically from // worst to best. @@ -9120,8 +9557,7 @@ public: CFP_Never, // Invalid caller/callee combination. CFP_WrongSide, // Calls from host-device to host or device // function that do not match current compilation - // mode. Only in effect if - // LangOpts.CUDADisableTargetCallChecks is true. + // mode. CFP_HostDevice, // Any calls to host/device functions. CFP_SameSide, // Calls from host-device to host or device // function matching current compilation mode. @@ -9139,23 +9575,48 @@ public: const FunctionDecl *Callee); /// Determines whether Caller may invoke Callee, based on their CUDA - /// host/device attributes. Returns true if the call is not allowed. - bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee) { - return IdentifyCUDAPreference(Caller, Callee) == CFP_Never; + /// host/device attributes. Returns false if the call is not allowed. + /// + /// Note: Will return true for CFP_WrongSide calls. These may appear in + /// semantically correct CUDA programs, but only if they're never codegen'ed. + bool IsAllowedCUDACall(const FunctionDecl *Caller, + const FunctionDecl *Callee) { + return IdentifyCUDAPreference(Caller, Callee) != CFP_Never; } /// May add implicit CUDAHostAttr and CUDADeviceAttr attributes to FD, /// depending on FD and the current compilation settings. - void maybeAddCUDAHostDeviceAttrs(Scope *S, FunctionDecl *FD, + void maybeAddCUDAHostDeviceAttrs(FunctionDecl *FD, const LookupResult &Previous); +public: + /// Check whether we're allowed to call Callee from the current context. + /// + /// - If the call is never allowed in a semantically-correct program + /// (CFP_Never), emits an error and returns false. + /// + /// - If the call is allowed in semantically-correct programs, but only if + /// it's never codegen'ed (CFP_WrongSide), creates a deferred diagnostic to + /// be emitted if and when the caller is codegen'ed, and returns true. + /// + /// Will only create deferred diagnostics for a given SourceLocation once, + /// so you can safely call this multiple times without generating duplicate + /// deferred errors. + /// + /// - Otherwise, returns true without emitting any diagnostics. + bool CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee); + + /// Set __device__ or __host__ __device__ attributes on the given lambda + /// operator() method. + /// + /// CUDA lambdas declared inside __device__ or __global__ functions inherit + /// the __device__ attribute. Similarly, lambdas inside __host__ __device__ + /// functions become __host__ __device__ themselves. + void CUDASetLambdaAttrs(CXXMethodDecl *Method); + /// Finds a function in \p Matches with highest calling priority /// from \p Caller context and erases all functions with lower /// calling priority. - void EraseUnwantedCUDAMatches(const FunctionDecl *Caller, - SmallVectorImpl<FunctionDecl *> &Matches); - void EraseUnwantedCUDAMatches(const FunctionDecl *Caller, - SmallVectorImpl<DeclAccessPair> &Matches); void EraseUnwantedCUDAMatches( const FunctionDecl *Caller, SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>> &Matches); @@ -9182,6 +9643,13 @@ public: bool isEmptyCudaConstructor(SourceLocation Loc, CXXConstructorDecl *CD); bool isEmptyCudaDestructor(SourceLocation Loc, CXXDestructorDecl *CD); + /// Check whether NewFD is a valid overload for CUDA. Emits + /// diagnostics and invalidates NewFD if not. + void checkCUDATargetOverload(FunctionDecl *NewFD, + const LookupResult &Previous); + /// Copies target attributes from the template TD to the function FD. + void inheritCUDATargetAttrs(FunctionDecl *FD, const FunctionTemplateDecl &TD); + /// \name Code completion //@{ /// \brief Describes the context in which code completion occurs. @@ -9241,8 +9709,8 @@ public: void CodeCompleteExpression(Scope *S, const CodeCompleteExpressionData &Data); void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, - SourceLocation OpLoc, - bool IsArrow); + SourceLocation OpLoc, bool IsArrow, + bool IsBaseExprStatement); void CodeCompletePostfixExpression(Scope *S, ExprResult LHS); void CodeCompleteTag(Scope *S, unsigned TagSpec); void CodeCompleteTypeQualifiers(DeclSpec &DS); @@ -9320,6 +9788,9 @@ public: bool AtParameterName, ParsedType ReturnType, ArrayRef<IdentifierInfo *> SelIdents); + void CodeCompleteObjCClassPropertyRefExpr(Scope *S, IdentifierInfo &ClassName, + SourceLocation ClassNameLoc, + bool IsBaseExprStatement); void CodeCompletePreprocessorDirective(bool InConditional); void CodeCompleteInPreprocessorConditionalExclusion(Scope *S); void CodeCompletePreprocessorMacroName(bool IsDefinition); @@ -9369,11 +9840,12 @@ private: SourceLocation Loc); void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, - ArrayRef<const Expr *> Args, bool IsMemberFunction, - SourceLocation Loc, SourceRange Range, + ArrayRef<const Expr *> Args, bool IsMemberFunction, + SourceLocation Loc, SourceRange Range, VariadicCallType CallType); bool CheckObjCString(Expr *Arg); + ExprResult CheckOSLogFormatStringArg(Expr *Arg); ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, CallExpr *TheCall); @@ -9386,6 +9858,7 @@ private: bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); @@ -9395,6 +9868,7 @@ private: bool SemaBuiltinVAStartARM(CallExpr *Call); bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs); + bool SemaBuiltinOSLogFormat(CallExpr *TheCall); public: // Used by C++ template instantiation. @@ -9405,6 +9879,7 @@ public: private: bool SemaBuiltinPrefetch(CallExpr *TheCall); + bool SemaBuiltinAllocaWithAlign(CallExpr *TheCall); bool SemaBuiltinAssume(CallExpr *TheCall); bool SemaBuiltinAssumeAligned(CallExpr *TheCall); bool SemaBuiltinLongjmp(CallExpr *TheCall); @@ -9432,12 +9907,13 @@ public: FST_Kprintf, FST_FreeBSDKPrintf, FST_OSTrace, + FST_OSLog, FST_Unknown }; static FormatStringType GetFormatStringType(const FormatAttr *Format); bool FormatStringHasSArg(const StringLiteral *FExpr); - + static bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx); private: @@ -9455,8 +9931,9 @@ private: llvm::SmallBitVector &CheckedVarArgs); void CheckAbsoluteValueFunction(const CallExpr *Call, - const FunctionDecl *FDecl, - IdentifierInfo *FnInfo); + const FunctionDecl *FDecl); + + void CheckMaxUnsignedZero(const CallExpr *Call, const FunctionDecl *FDecl); void CheckMemaccessArguments(const CallExpr *Call, unsigned BId, @@ -9535,6 +10012,10 @@ private: void CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr, const Expr * const *ExprArgs); + /// \brief Check if we are taking the address of a packed field + /// as this may be a problem if the pointer value is dereferenced. + void CheckAddressOfPackedMember(Expr *rhs); + /// \brief The parser's current scope. /// /// The parser maintains this state here. @@ -9590,8 +10071,17 @@ public: return OriginalLexicalContext ? OriginalLexicalContext : CurContext; } - AvailabilityResult getCurContextAvailability() const; - + /// \brief The diagnostic we should emit for \c D, or \c AR_Available. + /// + /// \param D The declaration to check. Note that this may be altered to point + /// to another declaration that \c D gets it's availability from. i.e., we + /// walk the list of typedefs to find an availability attribute. + /// + /// \param Message If non-null, this will be populated with the message from + /// the availability attribute that is selected. + AvailabilityResult ShouldDiagnoseAvailabilityOfDecl(NamedDecl *&D, + std::string *Message); + const DeclContext *getCurObjCLexicalContext() const { const DeclContext *DC = getCurLexicalContext(); // A category implicitly has the attribute of the interface. @@ -9613,6 +10103,53 @@ public: // Emitting members of dllexported classes is delayed until the class // (including field initializers) is fully parsed. SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses; + +private: + /// \brief Helper class that collects misaligned member designations and + /// their location info for delayed diagnostics. + struct MisalignedMember { + Expr *E; + RecordDecl *RD; + ValueDecl *MD; + CharUnits Alignment; + + MisalignedMember() : E(), RD(), MD(), Alignment() {} + MisalignedMember(Expr *E, RecordDecl *RD, ValueDecl *MD, + CharUnits Alignment) + : E(E), RD(RD), MD(MD), Alignment(Alignment) {} + explicit MisalignedMember(Expr *E) + : MisalignedMember(E, nullptr, nullptr, CharUnits()) {} + + bool operator==(const MisalignedMember &m) { return this->E == m.E; } + }; + /// \brief Small set of gathered accesses to potentially misaligned members + /// due to the packed attribute. + SmallVector<MisalignedMember, 4> MisalignedMembers; + + /// \brief Adds an expression to the set of gathered misaligned members. + void AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD, + CharUnits Alignment); + +public: + /// \brief Diagnoses the current set of gathered accesses. This typically + /// happens at full expression level. The set is cleared after emitting the + /// diagnostics. + void DiagnoseMisalignedMembers(); + + /// \brief This function checks if the expression is in the sef of potentially + /// misaligned members and it is converted to some pointer type T with lower + /// or equal alignment requirements. If so it removes it. This is used when + /// we do not want to diagnose such misaligned access (e.g. in conversions to + /// void*). + void DiscardMisalignedMemberAddress(const Type *T, Expr *E); + + /// \brief This function calls Action when it determines that E designates a + /// misaligned member due to the packed attribute. This is used to emit + /// local diagnostics like in reference binding. + void RefersToMemberWithReducedAlignment( + Expr *E, + llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> + Action); }; /// \brief RAII object that enters a new expression evaluation context. @@ -9636,7 +10173,7 @@ public: Sema::ReuseLambdaContextDecl_t, bool IsDecltype = false) : Actions(Actions) { - Actions.PushExpressionEvaluationContext(NewContext, + Actions.PushExpressionEvaluationContext(NewContext, Sema::ReuseLambdaContextDecl, IsDecltype); } @@ -9661,4 +10198,31 @@ struct LateParsedTemplate { } // end namespace clang +namespace llvm { +// Hash a FunctionDeclAndLoc by looking at both its FunctionDecl and its +// SourceLocation. +template <> struct DenseMapInfo<clang::Sema::FunctionDeclAndLoc> { + using FunctionDeclAndLoc = clang::Sema::FunctionDeclAndLoc; + using FDBaseInfo = DenseMapInfo<clang::CanonicalDeclPtr<clang::FunctionDecl>>; + + static FunctionDeclAndLoc getEmptyKey() { + return {FDBaseInfo::getEmptyKey(), clang::SourceLocation()}; + } + + static FunctionDeclAndLoc getTombstoneKey() { + return {FDBaseInfo::getTombstoneKey(), clang::SourceLocation()}; + } + + static unsigned getHashValue(const FunctionDeclAndLoc &FDL) { + return hash_combine(FDBaseInfo::getHashValue(FDL.FD), + FDL.Loc.getRawEncoding()); + } + + static bool isEqual(const FunctionDeclAndLoc &LHS, + const FunctionDeclAndLoc &RHS) { + return LHS.FD == RHS.FD && LHS.Loc == RHS.Loc; + } +}; +} // namespace llvm + #endif |