diff options
Diffstat (limited to 'include/clang/Sema/Sema.h')
-rw-r--r-- | include/clang/Sema/Sema.h | 825 |
1 files changed, 615 insertions, 210 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index e5b7465820a9..af762f74d745 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1,9 +1,8 @@ //===--- Sema.h - Semantic Analysis & AST Building --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -157,6 +156,7 @@ namespace clang { class OMPDeclareReductionDecl; class OMPDeclareSimdDecl; class OMPClause; + struct OMPVarListLocTy; struct OverloadCandidate; class OverloadCandidateSet; class OverloadExpr; @@ -274,6 +274,56 @@ public: } }; +/// Keeps track of expected type during expression parsing. The type is tied to +/// a particular token, all functions that update or consume the type take a +/// start location of the token they are looking at as a parameter. This allows +/// to avoid updating the type on hot paths in the parser. +class PreferredTypeBuilder { +public: + PreferredTypeBuilder() = default; + explicit PreferredTypeBuilder(QualType Type) : Type(Type) {} + + void enterCondition(Sema &S, SourceLocation Tok); + void enterReturn(Sema &S, SourceLocation Tok); + void enterVariableInit(SourceLocation Tok, Decl *D); + /// Computing a type for the function argument may require running + /// overloading, so we postpone its computation until it is actually needed. + /// + /// Clients should be very careful when using this funciton, as it stores a + /// function_ref, clients should make sure all calls to get() with the same + /// location happen while function_ref is alive. + void enterFunctionArgument(SourceLocation Tok, + llvm::function_ref<QualType()> ComputeType); + + void enterParenExpr(SourceLocation Tok, SourceLocation LParLoc); + void enterUnary(Sema &S, SourceLocation Tok, tok::TokenKind OpKind, + SourceLocation OpLoc); + void enterBinary(Sema &S, SourceLocation Tok, Expr *LHS, tok::TokenKind Op); + void enterMemAccess(Sema &S, SourceLocation Tok, Expr *Base); + void enterSubscript(Sema &S, SourceLocation Tok, Expr *LHS); + /// Handles all type casts, including C-style cast, C++ casts, etc. + void enterTypeCast(SourceLocation Tok, QualType CastType); + + QualType get(SourceLocation Tok) const { + if (Tok != ExpectedLoc) + return QualType(); + if (!Type.isNull()) + return Type; + if (ComputeType) + return ComputeType(); + return QualType(); + } + +private: + /// Start position of a token for which we store expected type. + SourceLocation ExpectedLoc; + /// Expected type for a token starting at ExpectedLoc. + QualType Type; + /// A function to compute expected type at ExpectedLoc. It is only considered + /// if Type is null. + llvm::function_ref<QualType()> ComputeType; +}; + /// Sema - This implements semantic analysis and AST building for C. class Sema { Sema(const Sema &) = delete; @@ -537,15 +587,15 @@ public: /// element type here is ExprWithCleanups::Object. SmallVector<BlockDecl*, 8> ExprCleanupObjects; - /// 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. - llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs; + /// Store a set 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. + using MaybeODRUseExprSet = llvm::SmallPtrSet<Expr *, 2>; + MaybeODRUseExprSet MaybeODRUseExprs; - std::unique_ptr<sema::FunctionScopeInfo> PreallocatedFunctionScope; + std::unique_ptr<sema::FunctionScopeInfo> CachedFunctionScope; /// Stack containing information about each of the nested /// function, block, and method scopes that are currently active. @@ -632,16 +682,6 @@ public: SmallVector<std::pair<FunctionDecl*, FunctionDecl*>, 2> DelayedEquivalentExceptionSpecChecks; - /// All the members seen during a class definition which were both - /// explicitly defaulted and had explicitly-specified exception - /// specifications, along with the function type containing their - /// user-specified exception specification. Those exception specifications - /// were overridden with the default specifications, but we still need to - /// check whether they are compatible with the default specification, and - /// we can't do that until the nesting set of class definitions is complete. - SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2> - DelayedDefaultedMemberExceptionSpecs; - typedef llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>> LateParsedTemplateMapT; @@ -757,6 +797,15 @@ public: } }; + /// Used to change context to isConstantEvaluated without pushing a heavy + /// ExpressionEvaluationContextRecord object. + bool isConstantEvaluatedOverride; + + bool isConstantEvaluated() { + return ExprEvalContexts.back().isConstantEvaluated() || + isConstantEvaluatedOverride; + } + /// RAII object to handle the state changes required to synthesize /// a function body. class SynthesizedFunctionScope { @@ -979,7 +1028,7 @@ public: /// context (i.e. the number of TypoExprs created). unsigned NumTypos; - llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs; + MaybeODRUseExprSet SavedMaybeODRUseExprs; /// The lambdas that are present within this context, if it /// is indeed an unevaluated context. @@ -1163,6 +1212,11 @@ public: /// of -Wselector. llvm::MapVector<Selector, SourceLocation> ReferencedSelectors; + /// List of SourceLocations where 'self' is implicitly retained inside a + /// block. + llvm::SmallVector<std::pair<SourceLocation, const BlockDecl *>, 1> + ImplicitlyRetainedSelfLocs; + /// Kinds of C++ special members. enum CXXSpecialMember { CXXDefaultConstructor, @@ -1331,8 +1385,21 @@ public: void emitAndClearUnusedLocalTypedefWarnings(); + enum TUFragmentKind { + /// The global module fragment, between 'module;' and a module-declaration. + Global, + /// A normal translation unit fragment. For a non-module unit, this is the + /// entire translation unit. Otherwise, it runs from the module-declaration + /// to the private-module-fragment (if any) or the end of the TU (if not). + Normal, + /// The private module fragment, between 'module :private;' and the end of + /// the translation unit. + Private + }; + void ActOnStartOfTranslationUnit(); void ActOnEndOfTranslationUnit(); + void ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind); void CheckDelegatingCtorCycles(); @@ -1350,10 +1417,24 @@ public: void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, RecordDecl *RD, CapturedRegionKind K); - void + + /// Custom deleter to allow FunctionScopeInfos to be kept alive for a short + /// time after they've been popped. + class PoppedFunctionScopeDeleter { + Sema *Self; + + public: + explicit PoppedFunctionScopeDeleter(Sema *Self) : Self(Self) {} + void operator()(sema::FunctionScopeInfo *Scope) const; + }; + + using PoppedFunctionScopePtr = + std::unique_ptr<sema::FunctionScopeInfo, PoppedFunctionScopeDeleter>; + + PoppedFunctionScopePtr PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP = nullptr, const Decl *D = nullptr, - const BlockExpr *blkExpr = nullptr); + QualType BlockType = QualType()); sema::FunctionScopeInfo *getCurFunction() const { return FunctionScopes.empty() ? nullptr : FunctionScopes.back(); @@ -1369,7 +1450,6 @@ public: void PopCompoundScope(); sema::CompoundScopeInfo &getCurCompoundScope() const; - bool isCurCompoundStmtAStmtExpr() const; bool hasAnyUnrecoverableErrorsInThisFunction() const; @@ -1412,6 +1492,10 @@ public: QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc); QualType BuildExtVectorType(QualType T, Expr *ArraySize, SourceLocation AttrLoc); + QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace, + SourceLocation AttrLoc); + + /// Same as above, but constructs the AddressSpace index if not provided. QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace, SourceLocation AttrLoc); @@ -1489,6 +1573,7 @@ public: bool CheckExceptionSpecSubset(const PartialDiagnostic &DiagID, const PartialDiagnostic &NestedDiagID, const PartialDiagnostic &NoteID, + const PartialDiagnostic &NoThrowDiagID, const FunctionProtoType *Superset, SourceLocation SuperLoc, const FunctionProtoType *Subset, @@ -1571,13 +1656,18 @@ private: TypeDiagnoser *Diagnoser); struct ModuleScope { + SourceLocation BeginLoc; clang::Module *Module = nullptr; bool ModuleInterface = false; + bool ImplicitGlobalModuleFragment = false; VisibleModuleSet OuterVisibleModules; }; /// The modules we're currently parsing. llvm::SmallVector<ModuleScope, 16> ModuleScopes; + /// Namespace definitions that we will export when they finish. + llvm::SmallPtrSet<const NamespaceDecl*, 8> DeferredExportedNamespaces; + /// Get the module whose scope we are currently within. Module *getCurrentModule() const { return ModuleScopes.empty() ? nullptr : ModuleScopes.back().Module; @@ -1757,7 +1847,8 @@ public: NC_NestedNameSpecifier, NC_TypeTemplate, NC_VarTemplate, - NC_FunctionTemplate + NC_FunctionTemplate, + NC_UndeclaredTemplate, }; class NameClassification { @@ -1805,6 +1896,12 @@ public: return Result; } + static NameClassification UndeclaredTemplate(TemplateName Name) { + NameClassification Result(NC_UndeclaredTemplate); + Result.Template = Name; + return Result; + } + NameClassificationKind getKind() const { return Kind; } ParsedType getType() const { @@ -1819,7 +1916,7 @@ public: TemplateName getTemplateName() const { assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || - Kind == NC_VarTemplate); + Kind == NC_VarTemplate || Kind == NC_UndeclaredTemplate); return Template; } @@ -1831,6 +1928,8 @@ public: return TNK_Function_template; case NC_VarTemplate: return TNK_Var_template; + case NC_UndeclaredTemplate: + return TNK_Undeclared_template; default: llvm_unreachable("unsupported name classification."); } @@ -1861,11 +1960,11 @@ public: /// expression. /// /// \param CCC The correction callback, if typo correction is desired. - NameClassification - ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, - SourceLocation NameLoc, const Token &NextToken, - bool IsAddressOfOperand, - std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr); + NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, + IdentifierInfo *&Name, SourceLocation NameLoc, + const Token &NextToken, + bool IsAddressOfOperand, + CorrectionCandidateCallback *CCC = nullptr); /// Describes the detailed kind of a template name. Used in diagnostics. enum class TemplateNameKindForDiagnostics { @@ -1874,6 +1973,7 @@ public: VarTemplate, AliasTemplate, TemplateTemplateParam, + Concept, DependentTemplate }; TemplateNameKindForDiagnostics @@ -1964,7 +2064,7 @@ public: bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); void CheckVariableDeclarationType(VarDecl *NewVD); bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, - Expr *&Init); + Expr *Init); void CheckCompleteVariableDeclaration(VarDecl *VD); void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD); void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); @@ -1993,7 +2093,9 @@ public: QualType NewT, QualType OldT); void CheckMain(FunctionDecl *FD, const DeclSpec &D); void CheckMSVCRTEntryPoint(FunctionDecl *FD); - Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, bool IsDefinition); + Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, + bool IsDefinition); + void CheckFunctionOrTemplateParamDeclarator(Scope *S, Declarator &D); Decl *ActOnParamDeclarator(Scope *S, Declarator &D); ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, @@ -2012,6 +2114,48 @@ public: bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc); + // Contexts where using non-trivial C union types can be disallowed. This is + // passed to err_non_trivial_c_union_in_invalid_context. + enum NonTrivialCUnionContext { + // Function parameter. + NTCUC_FunctionParam, + // Function return. + NTCUC_FunctionReturn, + // Default-initialized object. + NTCUC_DefaultInitializedObject, + // Variable with automatic storage duration. + NTCUC_AutoVar, + // Initializer expression that might copy from another object. + NTCUC_CopyInit, + // Assignment. + NTCUC_Assignment, + // Compound literal. + NTCUC_CompoundLiteral, + // Block capture. + NTCUC_BlockCapture, + // lvalue-to-rvalue conversion of volatile type. + NTCUC_LValueToRValueVolatile, + }; + + /// Emit diagnostics if the initializer or any of its explicit or + /// implicitly-generated subexpressions require copying or + /// default-initializing a type that is or contains a C union type that is + /// non-trivial to copy or default-initialize. + void checkNonTrivialCUnionInInitializer(const Expr *Init, SourceLocation Loc); + + // These flags are passed to checkNonTrivialCUnion. + enum NonTrivialCUnionKind { + NTCUK_Init = 0x1, + NTCUK_Destruct = 0x2, + NTCUK_Copy = 0x4, + }; + + /// Emit diagnostics if a non-trivial C union type or a struct that contains + /// a non-trivial C union is used in an invalid context. + void checkNonTrivialCUnion(QualType QT, SourceLocation Loc, + NonTrivialCUnionContext UseContext, + unsigned NonTrivialKind); + void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit); void ActOnUninitializedDecl(Decl *dcl); void ActOnInitializerError(Decl *Dcl); @@ -2102,24 +2246,40 @@ public: enum class ModuleDeclKind { Interface, ///< 'export module X;' Implementation, ///< 'module X;' - Partition, ///< 'module partition X;' }; /// The parser has processed a module-declaration that begins the definition /// of a module interface or implementation. DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, - ModuleIdPath Path); + ModuleIdPath Path, bool IsFirstDecl); + + /// The parser has processed a global-module-fragment declaration that begins + /// the definition of the global module fragment of the current module unit. + /// \param ModuleLoc The location of the 'module' keyword. + DeclGroupPtrTy ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc); + + /// The parser has processed a private-module-fragment declaration that begins + /// the definition of the private module fragment of the current module unit. + /// \param ModuleLoc The location of the 'module' keyword. + /// \param PrivateLoc The location of the 'private' keyword. + DeclGroupPtrTy ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, + SourceLocation PrivateLoc); /// The parser has processed a module import declaration. /// - /// \param AtLoc The location of the '@' symbol, if any. - /// + /// \param StartLoc The location of the first token in the declaration. This + /// could be the location of an '@', 'export', or 'import'. + /// \param ExportLoc The location of the 'export' keyword, if any. /// \param ImportLoc The location of the 'import' keyword. - /// /// \param Path The module access path. - DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, - ModuleIdPath Path); + DeclResult ActOnModuleImport(SourceLocation StartLoc, + SourceLocation ExportLoc, + SourceLocation ImportLoc, ModuleIdPath Path); + DeclResult ActOnModuleImport(SourceLocation StartLoc, + SourceLocation ExportLoc, + SourceLocation ImportLoc, Module *M, + ModuleIdPath Path = {}); /// The parser has processed a module import translated from a /// #include or similar preprocessing directive. @@ -2413,14 +2573,6 @@ public: /// Add this decl to the scope shadowed decl chains. void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true); - /// Make the given externally-produced declaration visible at the - /// top level scope. - /// - /// \param D The externally-produced declaration to push. - /// - /// \param Name The name of the externally-produced declaration. - void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name); - /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns /// true if 'D' belongs to the given declaration context. @@ -2456,18 +2608,38 @@ public: AMK_ProtocolImplementation, }; + /// Describes the kind of priority given to an availability attribute. + /// + /// The sum of priorities deteremines the final priority of the attribute. + /// The final priority determines how the attribute will be merged. + /// An attribute with a lower priority will always remove higher priority + /// attributes for the specified platform when it is being applied. An + /// attribute with a higher priority will not be applied if the declaration + /// already has an availability attribute with a lower priority for the + /// specified platform. The final prirority values are not expected to match + /// the values in this enumeration, but instead should be treated as a plain + /// integer value. This enumeration just names the priority weights that are + /// used to calculate that final vaue. + enum AvailabilityPriority : int { + /// The availability attribute was specified explicitly next to the + /// declaration. + AP_Explicit = 0, + + /// The availability attribute was applied using '#pragma clang attribute'. + AP_PragmaClangAttribute = 1, + + /// The availability attribute for a specific platform was inferred from + /// an availability attribute for another platform. + AP_InferredFromOtherPlatform = 2 + }; + /// Attribute merging methods. Return true if a new attribute was added. - AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, - IdentifierInfo *Platform, - bool Implicit, - VersionTuple Introduced, - VersionTuple Deprecated, - VersionTuple Obsoleted, - bool IsUnavailable, - StringRef Message, - bool IsStrict, StringRef Replacement, - AvailabilityMergeKind AMK, - unsigned AttrSpellingListIndex); + AvailabilityAttr *mergeAvailabilityAttr( + NamedDecl *D, SourceRange Range, IdentifierInfo *Platform, bool Implicit, + VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, + bool IsUnavailable, StringRef Message, bool IsStrict, + StringRef Replacement, AvailabilityMergeKind AMK, int Priority, + unsigned AttrSpellingListIndex); TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range, TypeVisibilityAttr::VisibilityType Vis, unsigned AttrSpellingListIndex); @@ -2496,6 +2668,12 @@ public: unsigned AttrSpellingListIndex); MinSizeAttr *mergeMinSizeAttr(Decl *D, SourceRange Range, unsigned AttrSpellingListIndex); + NoSpeculativeLoadHardeningAttr * + mergeNoSpeculativeLoadHardeningAttr(Decl *D, + const NoSpeculativeLoadHardeningAttr &AL); + SpeculativeLoadHardeningAttr * + mergeSpeculativeLoadHardeningAttr(Decl *D, + const SpeculativeLoadHardeningAttr &AL); OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range, unsigned AttrSpellingListIndex); InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL); @@ -2555,13 +2733,6 @@ public: bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl, bool ConsiderCudaAttrs = true); - /// Checks availability of the function depending on the current - /// function context.Inside an unavailable function,unavailability is ignored. - /// - /// \returns true if \p FD is unavailable and current context is inside - /// an available function, false otherwise. - bool isFunctionConsideredUnavailable(FunctionDecl *FD); - ImplicitConversionSequence TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, @@ -2641,7 +2812,8 @@ public: CCEK_Enumerator, ///< Enumerator value with fixed underlying type. CCEK_TemplateArg, ///< Value of a non-type template parameter. CCEK_NewExpr, ///< Constant expression in a noptr-new-declarator. - CCEK_ConstexprIf ///< Condition in a constexpr if statement. + CCEK_ConstexprIf, ///< Condition in a constexpr if statement. + CCEK_ExplicitBool ///< Condition in an explicit(bool) specifier. }; ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE); @@ -2763,7 +2935,8 @@ public: OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false, bool PartialOverloading = false, - bool AllowExplicit = false, + bool AllowExplicit = true, + bool AllowExplicitConversion = false, ADLCallKind IsADLCandidate = ADLCallKind::NotADL, ConversionSequenceList EarlyConversions = None); void AddFunctionCandidates(const UnresolvedSetImpl &Functions, @@ -2802,7 +2975,7 @@ public: FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false, - bool PartialOverloading = false, + bool PartialOverloading = false, bool AllowExplicit = true, ADLCallKind IsADLCandidate = ADLCallKind::NotADL); bool CheckNonDependentConversions(FunctionTemplateDecl *FunctionTemplate, ArrayRef<QualType> ParamTypes, @@ -2814,20 +2987,16 @@ public: QualType ObjectType = QualType(), Expr::Classification ObjectClassification = {}); - void AddConversionCandidate(CXXConversionDecl *Conversion, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingContext, - Expr *From, QualType ToType, - OverloadCandidateSet& CandidateSet, - bool AllowObjCConversionOnExplicit, - bool AllowResultConversion = true); - void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingContext, - Expr *From, QualType ToType, - OverloadCandidateSet &CandidateSet, - bool AllowObjCConversionOnExplicit, - bool AllowResultConversion = true); + void AddConversionCandidate( + CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, + CXXRecordDecl *ActingContext, Expr *From, QualType ToType, + OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, + bool AllowExplicit, bool AllowResultConversion = true); + void AddTemplateConversionCandidate( + FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, + CXXRecordDecl *ActingContext, Expr *From, QualType ToType, + OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, + bool AllowExplicit, bool AllowResultConversion = true); void AddSurrogateCandidate(CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, @@ -3091,6 +3260,8 @@ public: LookupObjCImplicitSelfParam, /// Look up the name of an OpenMP user-defined reduction operation. LookupOMPReductionName, + /// Look up the name of an OpenMP user-defined mapper. + LookupOMPMapperName, /// Look up any declaration with any name. LookupAnyName }; @@ -3192,7 +3363,7 @@ private: makeTypoCorrectionConsumer(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, + CorrectionCandidateCallback &CCC, DeclContext *MemberContext, bool EnteringContext, const ObjCObjectPointerType *OPT, bool ErrorRecovery); @@ -3276,7 +3447,7 @@ public: TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, + CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext = nullptr, bool EnteringContext = false, @@ -3286,7 +3457,7 @@ public: TypoExpr *CorrectTypoDelayed(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, + CorrectionCandidateCallback &CCC, TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode, DeclContext *MemberContext = nullptr, @@ -3411,7 +3582,7 @@ public: // Check if there is an explicit attribute, but only look through parens. // The intent is to look for an attribute on the current declarator, but not // one that came from a typedef. - bool hasExplicitCallingConv(QualType &T); + bool hasExplicitCallingConv(QualType T); /// Get the outermost AttributedType node that sets a calling convention. /// Valid types should not have multiple attributes with different CCs. @@ -3869,6 +4040,7 @@ public: unsigned NumInputs, IdentifierInfo **Names, MultiExprArg Constraints, MultiExprArg Exprs, Expr *AsmString, MultiExprArg Clobbers, + unsigned NumLabels, SourceLocation RParenLoc); void FillInlineAsmIdentifierInfo(Expr *Res, @@ -4021,7 +4193,6 @@ public: ObjCInterfaceDecl *ClassReciever = nullptr); void NoteDeletedFunction(FunctionDecl *FD); void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD); - std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD); bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc); @@ -4064,8 +4235,11 @@ public: void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var); void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base = nullptr); void MarkMemberReferenced(MemberExpr *E); + void MarkFunctionParmPackReferenced(FunctionParmPackExpr *E); + void MarkCaptureUsedInEnclosingContext(VarDecl *Capture, SourceLocation Loc, + unsigned CapturingScopeIndex); - void UpdateMarkingForLValueToRValue(Expr *E); + ExprResult CheckLValueToRValueConversionOperand(Expr *E); void CleanupVarDeclMarking(); enum TryCaptureKind { @@ -4150,6 +4324,10 @@ public: /// If it is unreachable, the diagnostic will not be emitted. bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD); + /// Similar, but diagnostic is only produced if all the specified statements + /// are reachable. + bool DiagRuntimeBehavior(SourceLocation Loc, ArrayRef<const Stmt*> Stmts, + const PartialDiagnostic &PD); // Primary Expressions. SourceRange getExprRange(Expr *E) const; @@ -4157,7 +4335,7 @@ public: ExprResult ActOnIdExpression( Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, - std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr, + CorrectionCandidateCallback *CCC = nullptr, bool IsInlineAsmIdentifier = false, Token *KeywordReplacement = nullptr); void DecomposeUnqualifiedId(const UnqualifiedId &Id, @@ -4167,7 +4345,7 @@ public: bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - std::unique_ptr<CorrectionCandidateCallback> CCC, + CorrectionCandidateCallback &CCC, TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, ArrayRef<Expr *> Args = None, TypoExpr **Out = nullptr); @@ -4181,16 +4359,28 @@ public: bool isAddressOfOperand, const TemplateArgumentListInfo *TemplateArgs); - ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, - ExprValueKind VK, - SourceLocation Loc, - const CXXScopeSpec *SS = nullptr); - ExprResult + /// If \p D cannot be odr-used in the current expression evaluation context, + /// return a reason explaining why. Otherwise, return NOUR_None. + NonOdrUseReason getNonOdrUseReasonInCurrentContext(ValueDecl *D); + + DeclRefExpr *BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, + SourceLocation Loc, + const CXXScopeSpec *SS = nullptr); + DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, const DeclarationNameInfo &NameInfo, const CXXScopeSpec *SS = nullptr, NamedDecl *FoundD = nullptr, + SourceLocation TemplateKWLoc = SourceLocation(), + const TemplateArgumentListInfo *TemplateArgs = nullptr); + DeclRefExpr * + BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, + const DeclarationNameInfo &NameInfo, + NestedNameSpecifierLoc NNS, + NamedDecl *FoundD = nullptr, + SourceLocation TemplateKWLoc = SourceLocation(), const TemplateArgumentListInfo *TemplateArgs = nullptr); + ExprResult BuildAnonymousStructUnionMemberReference( const CXXScopeSpec &SS, @@ -4378,6 +4568,23 @@ public: UnqualifiedId &Member, Decl *ObjCImpDecl); + MemberExpr * + BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, + const CXXScopeSpec *SS, SourceLocation TemplateKWLoc, + ValueDecl *Member, DeclAccessPair FoundDecl, + bool HadMultipleCandidates, + const DeclarationNameInfo &MemberNameInfo, QualType Ty, + ExprValueKind VK, ExprObjectKind OK, + const TemplateArgumentListInfo *TemplateArgs = nullptr); + MemberExpr * + BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, + NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, + ValueDecl *Member, DeclAccessPair FoundDecl, + bool HadMultipleCandidates, + const DeclarationNameInfo &MemberNameInfo, QualType Ty, + ExprValueKind VK, ExprObjectKind OK, + const TemplateArgumentListInfo *TemplateArgs = nullptr); + void ActOnDefaultCtorInitializers(Decl *CDtorDecl); bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, FunctionDecl *FDecl, @@ -4394,6 +4601,9 @@ public: /// locations. ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, + Expr *ExecConfig = nullptr); + ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, + MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig = nullptr, bool IsExecConfig = false); ExprResult @@ -4467,6 +4677,8 @@ public: void ActOnStartStmtExpr(); ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc); // "({..})" + // Handle the final expression in a statement expression. + ExprResult ActOnStmtExprResult(ExprResult E); void ActOnStmtExprError(); // __builtin_offsetof(type, identifier(.identifier|[expr])*) @@ -4502,6 +4714,17 @@ public: ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, TypeSourceInfo *TInfo, SourceLocation RPLoc); + // __builtin_LINE(), __builtin_FUNCTION(), __builtin_FILE(), + // __builtin_COLUMN() + ExprResult ActOnSourceLocExpr(SourceLocExpr::IdentKind Kind, + SourceLocation BuiltinLoc, + SourceLocation RPLoc); + + // Build a potentially resolved SourceLocExpr. + ExprResult BuildSourceLocExpr(SourceLocExpr::IdentKind Kind, + SourceLocation BuiltinLoc, SourceLocation RPLoc, + DeclContext *ParentContext); + // __null ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc); @@ -5056,6 +5279,13 @@ public: SourceRange AngleBrackets, SourceRange Parens); + ExprResult ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &Dcl, + ExprResult Operand, + SourceLocation RParenLoc); + + ExprResult BuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, + Expr *Operand, SourceLocation RParenLoc); + ExprResult BuildCXXTypeId(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, @@ -5094,13 +5324,18 @@ public: ExprResult BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Operator, SourceLocation EllipsisLoc, Expr *RHS, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + Optional<unsigned> NumExpansions); ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, BinaryOperatorKind Operator); //// ActOnCXXThis - Parse 'this' pointer. ExprResult ActOnCXXThis(SourceLocation loc); + /// Build a CXXThisExpr and mark it referenced in the current context. + Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit); + void MarkThisReferenced(CXXThisExpr *This); + /// Try to retrieve the type of the 'this' pointer. /// /// \returns The type of 'this', if possible. Otherwise, returns a NULL type. @@ -5204,7 +5439,7 @@ public: SourceRange TypeIdParens, QualType AllocType, TypeSourceInfo *AllocTypeInfo, - Expr *ArraySize, + Optional<Expr *> ArraySize, SourceRange DirectInitRange, Expr *Initializer); @@ -5568,12 +5803,12 @@ public: LambdaCaptureDefault CaptureDefault); /// Start the definition of a lambda expression. - CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class, - SourceRange IntroducerRange, - TypeSourceInfo *MethodType, - SourceLocation EndLoc, - ArrayRef<ParmVarDecl *> Params, - bool IsConstexprSpecified); + CXXMethodDecl * + startLambdaDefinition(CXXRecordDecl *Class, SourceRange IntroducerRange, + TypeSourceInfo *MethodType, SourceLocation EndLoc, + ArrayRef<ParmVarDecl *> Params, + ConstexprSpecKind ConstexprKind, + Optional<std::pair<unsigned, Decl *>> Mangling = None); /// Endow the lambda scope info with the relevant properties. void buildLambdaScope(sema::LambdaScopeInfo *LSI, @@ -5589,14 +5824,16 @@ public: /// any implicit conversions such as an lvalue-to-rvalue conversion if /// not being used to initialize a reference. ParsedType actOnLambdaInitCaptureInitialization( - SourceLocation Loc, bool ByRef, IdentifierInfo *Id, - LambdaCaptureInitKind InitKind, Expr *&Init) { + SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, + IdentifierInfo *Id, LambdaCaptureInitKind InitKind, Expr *&Init) { return ParsedType::make(buildLambdaInitCaptureInitialization( - Loc, ByRef, Id, InitKind != LambdaCaptureInitKind::CopyInit, Init)); + Loc, ByRef, EllipsisLoc, None, Id, + InitKind != LambdaCaptureInitKind::CopyInit, Init)); } - QualType buildLambdaInitCaptureInitialization(SourceLocation Loc, bool ByRef, - IdentifierInfo *Id, - bool DirectInit, Expr *&Init); + QualType buildLambdaInitCaptureInitialization( + SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, + Optional<unsigned> NumExpansions, IdentifierInfo *Id, bool DirectInit, + Expr *&Init); /// Create a dummy variable within the declcontext of the lambda's /// call operator, for name lookup purposes for a lambda init capture. @@ -5605,16 +5842,23 @@ public: /// variables appropriately. VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc, QualType InitCaptureType, + SourceLocation EllipsisLoc, IdentifierInfo *Id, unsigned InitStyle, Expr *Init); - /// Build the implicit field for an init-capture. - FieldDecl *buildInitCaptureField(sema::LambdaScopeInfo *LSI, VarDecl *Var); + /// Add an init-capture to a lambda scope. + void addInitCapture(sema::LambdaScopeInfo *LSI, VarDecl *Var); /// Note that we have finished the explicit captures for the /// given lambda. void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI); + /// \brief This is called after parsing the explicit template parameter list + /// on a lambda (if it exists) in C++2a. + void ActOnLambdaExplicitTemplateParameterList(SourceLocation LAngleLoc, + ArrayRef<NamedDecl *> TParams, + SourceLocation RAngleLoc); + /// Introduce the lambda parameters into scope. void addLambdaParameters( ArrayRef<LambdaIntroducer::LambdaCapture> Captures, @@ -5649,6 +5893,14 @@ public: bool DiagnoseUnusedLambdaCapture(SourceRange CaptureRange, const sema::Capture &From); + /// Build a FieldDecl suitable to hold the given capture. + FieldDecl *BuildCaptureField(RecordDecl *RD, const sema::Capture &Capture); + + /// Initialize the given capture with a suitable expression. + ExprResult BuildCaptureInit(const sema::Capture &Capture, + SourceLocation ImplicitCaptureLoc, + bool IsOpenMPMapping = false); + /// Complete a lambda-expression having processed and attached the /// lambda body. ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, @@ -5868,8 +6120,8 @@ public: /// MarkVirtualMembersReferenced - Will mark all members of the given /// CXXRecordDecl referenced. - void MarkVirtualMembersReferenced(SourceLocation Loc, - const CXXRecordDecl *RD); + void MarkVirtualMembersReferenced(SourceLocation Loc, const CXXRecordDecl *RD, + bool ConstexprOnly = false); /// Define all of the vtables that have been used in this /// translation unit and reference any virtual members used by those @@ -5956,8 +6208,6 @@ public: void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD); void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD); - void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD, - const FunctionProtoType *T); void CheckDelayedMemberExceptionSpecs(); //===--------------------------------------------------------------------===// @@ -6145,14 +6395,37 @@ public: // C++ Templates [C++ 14] // void FilterAcceptableTemplateNames(LookupResult &R, - bool AllowFunctionTemplates = true); + bool AllowFunctionTemplates = true, + bool AllowDependent = true); bool hasAnyAcceptableTemplateNames(LookupResult &R, - bool AllowFunctionTemplates = true); - + bool AllowFunctionTemplates = true, + bool AllowDependent = true, + bool AllowNonTemplateFunctions = false); + /// Try to interpret the lookup result D as a template-name. + /// + /// \param D A declaration found by name lookup. + /// \param AllowFunctionTemplates Whether function templates should be + /// considered valid results. + /// \param AllowDependent Whether unresolved using declarations (that might + /// name templates) should be considered valid results. + NamedDecl *getAsTemplateNameDecl(NamedDecl *D, + bool AllowFunctionTemplates = true, + bool AllowDependent = true); + + enum class AssumedTemplateKind { + /// This is not assumed to be a template name. + None, + /// This is assumed to be a template name because lookup found nothing. + FoundNothing, + /// This is assumed to be a template name because lookup found one or more + /// functions (but no function templates). + FoundFunctions, + }; bool LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType, bool EnteringContext, bool &MemberOfUnknownSpecialization, - SourceLocation TemplateKWLoc = SourceLocation()); + SourceLocation TemplateKWLoc = SourceLocation(), + AssumedTemplateKind *ATK = nullptr); TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, @@ -6163,6 +6436,20 @@ public: TemplateTy &Template, bool &MemberOfUnknownSpecialization); + /// Try to resolve an undeclared template name as a type template. + /// + /// Sets II to the identifier corresponding to the template name, and updates + /// Name to a corresponding (typo-corrected) type template name and TNK to + /// the corresponding kind, if possible. + void ActOnUndeclaredTypeTemplateName(Scope *S, TemplateTy &Name, + TemplateNameKind &TNK, + SourceLocation NameLoc, + IdentifierInfo *&II); + + bool resolveAssumedTemplateNameAsType(Scope *S, TemplateName &Name, + SourceLocation NameLoc, + bool Diagnose = true); + /// Determine whether a particular identifier might be the name in a C++1z /// deduction-guide declaration. bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, @@ -6272,14 +6559,11 @@ public: TemplateArgumentListInfo &TemplateArgs); TypeResult - ActOnTemplateIdType(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, + ActOnTemplateIdType(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, TemplateTy Template, IdentifierInfo *TemplateII, - SourceLocation TemplateIILoc, - SourceLocation LAngleLoc, - ASTTemplateArgsPtr TemplateArgs, - SourceLocation RAngleLoc, - bool IsCtorOrDtorName = false, - bool IsClassName = false); + SourceLocation TemplateIILoc, SourceLocation LAngleLoc, + ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, + bool IsCtorOrDtorName = false, bool IsClassName = false); /// Parsed an elaborated-type-specifier that refers to a template-id, /// such as \c class T::template apply<U>. @@ -6310,6 +6594,13 @@ public: SourceLocation TemplateLoc, const TemplateArgumentListInfo *TemplateArgs); + ExprResult + CheckConceptTemplateId(const CXXScopeSpec &SS, + const DeclarationNameInfo &NameInfo, + ConceptDecl *Template, + SourceLocation TemplateLoc, + const TemplateArgumentListInfo *TemplateArgs); + void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc); ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, @@ -6577,6 +6868,11 @@ public: const TemplateArgument *Args, unsigned NumArgs); + // Concepts + Decl *ActOnConceptDefinition( + Scope *S, MultiTemplateParamsArg TemplateParameterLists, + IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr); + //===--------------------------------------------------------------------===// // C++ Variadic Templates (C++0x [temp.variadic]) //===--------------------------------------------------------------------===// @@ -7099,7 +7395,7 @@ public: QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, QualType Type, TypeSourceInfo *TSI, SourceRange Range, bool DirectInit, - Expr *&Init); + Expr *Init); TypeLoc getReturnTypeLoc(FunctionDecl *FD) const; @@ -7271,8 +7567,10 @@ public: SourceRange InstantiationRange; CodeSynthesisContext() - : Kind(TemplateInstantiation), Entity(nullptr), Template(nullptr), - TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {} + : Kind(TemplateInstantiation), + SavedInNonInstantiationSFINAEContext(false), Entity(nullptr), + Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0), + DeductionInfo(nullptr) {} /// Determines whether this template is an actual instantiation /// that should be counted toward the maximum instantiation depth. @@ -7925,7 +8223,8 @@ public: LateInstantiatedAttrVec *LateAttrs, DeclContext *Owner, LocalInstantiationScope *StartingScope, - bool InstantiatingVarTemplate = false); + bool InstantiatingVarTemplate = false, + VarTemplateSpecializationDecl *PrevVTSD = nullptr); void InstantiateVariableInitializer( VarDecl *Var, VarDecl *OldVar, const MultiLevelTemplateArgumentList &TemplateArgs); @@ -8018,17 +8317,19 @@ public: const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList); - Decl *ActOnStartClassImplementation( - SourceLocation AtClassImplLoc, - IdentifierInfo *ClassName, SourceLocation ClassLoc, - IdentifierInfo *SuperClassname, - SourceLocation SuperClassLoc); + Decl *ActOnStartClassImplementation(SourceLocation AtClassImplLoc, + IdentifierInfo *ClassName, + SourceLocation ClassLoc, + IdentifierInfo *SuperClassname, + SourceLocation SuperClassLoc, + const ParsedAttributesView &AttrList); Decl *ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *CatName, - SourceLocation CatLoc); + SourceLocation CatLoc, + const ParsedAttributesView &AttrList); DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef<Decl *> Decls); @@ -8579,6 +8880,16 @@ public: void AddXConsumedAttr(Decl *D, SourceRange SR, unsigned SpellingIndex, RetainOwnershipKind K, bool IsTemplateInstantiation); + /// addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size + /// attribute to a particular declaration. + void addAMDGPUFlatWorkGroupSizeAttr(SourceRange AttrRange, Decl *D, Expr *Min, + Expr *Max, unsigned SpellingListIndex); + + /// addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a + /// particular declaration. + void addAMDGPUWavesPerEUAttr(SourceRange AttrRange, Decl *D, Expr *Min, + Expr *Max, unsigned SpellingListIndex); + bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type); //===--------------------------------------------------------------------===// @@ -8697,6 +9008,13 @@ private: /// Pop OpenMP function region for non-capturing function. void popOpenMPFunctionRegion(const sema::FunctionScopeInfo *OldFSI); + /// Check whether we're allowed to call Callee from the current function. + void checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee); + + /// Check if the expression is allowed to be used in expressions for the + /// OpenMP devices. + void checkOpenMPDeviceExpr(const Expr *E); + /// 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. @@ -8713,6 +9031,10 @@ private: SourceRange SrcRange = SourceRange()); public: + /// Function tries to capture lambda's captured variables in the OpenMP region + /// before the original lambda is captured. + void tryCaptureOpenMPLambdas(ValueDecl *V); + /// Return true if the provided declaration \a VD should be captured by /// reference. /// \param Level Relative level of nested OpenMP construct for that the check @@ -8722,7 +9044,8 @@ public: /// Check if the specified variable is used in one of the private /// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP /// constructs. - VarDecl *isOpenMPCapturedDecl(ValueDecl *D); + VarDecl *isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo = false, + unsigned StopAt = 0); ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc); @@ -8767,9 +9090,9 @@ public: // OpenMP directives and clauses. /// Called on correct id-expression from the '#pragma omp /// threadprivate'. - ExprResult ActOnOpenMPIdExpression(Scope *CurScope, - CXXScopeSpec &ScopeSpec, - const DeclarationNameInfo &Id); + ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, + const DeclarationNameInfo &Id, + OpenMPDirectiveKind Kind); /// Called on well-formed '#pragma omp threadprivate'. DeclGroupPtrTy ActOnOpenMPThreadprivateDirective( SourceLocation Loc, @@ -8777,6 +9100,11 @@ public: /// Builds a new OpenMPThreadPrivateDecl and checks its correctness. OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList); + /// Called on well-formed '#pragma omp allocate'. + DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, + ArrayRef<Expr *> VarList, + ArrayRef<OMPClause *> Clauses, + DeclContext *Owner = nullptr); /// Called on well-formed '#pragma omp requires'. DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef<OMPClause *> ClauseList); @@ -8806,6 +9134,27 @@ public: DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd( Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid); + /// Check variable declaration in 'omp declare mapper' construct. + TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D); + /// Check if the specified type is allowed to be used in 'omp declare + /// mapper' construct. + QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, + TypeResult ParsedType); + /// Called on start of '#pragma omp declare mapper'. + OMPDeclareMapperDecl *ActOnOpenMPDeclareMapperDirectiveStart( + Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, + SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, + Decl *PrevDeclInScope = nullptr); + /// Build the mapper variable of '#pragma omp declare mapper'. + void ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, + Scope *S, QualType MapperType, + SourceLocation StartLoc, + DeclarationName VN); + /// Called at the end of '#pragma omp declare mapper'. + DeclGroupPtrTy + ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, + ArrayRef<OMPClause *> ClauseList); + /// Called on the start of target region i.e. '#pragma omp declare target'. bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc); /// Called at the end of target region i.e. '#pragme omp end declare target'. @@ -8825,12 +9174,6 @@ public: } /// Return true inside OpenMP target region. bool isInOpenMPTargetExecutionDirective() const; - /// Return true if (un)supported features for the current target should be - /// diagnosed if OpenMP (offloading) is enabled. - bool shouldDiagnoseTargetSupportFromOpenMP() const { - return !getLangOpts().OpenMPIsDevice || isInOpenMPDeclareTargetContext() || - isInOpenMPTargetExecutionDirective(); - } /// Return the number of captured regions created for an OpenMP directive. static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind); @@ -9110,6 +9453,11 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// Called on well-formed 'allocator' clause. + OMPClause *ActOnOpenMPAllocatorClause(Expr *Allocator, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// Called on well-formed 'if' clause. OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, @@ -9176,7 +9524,7 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); - + OMPClause *ActOnOpenMPSingleExprWithArgClause( OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -9231,7 +9579,7 @@ public: /// Called on well-formed 'unified_address' clause. OMPClause *ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc); - + /// Called on well-formed 'reverse_offload' clause. OMPClause *ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc); @@ -9247,15 +9595,18 @@ public: OMPClause *ActOnOpenMPVarListClause( OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ColonLoc, SourceLocation EndLoc, - CXXScopeSpec &ReductionIdScopeSpec, - const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, + const OMPVarListLocTy &Locs, SourceLocation ColonLoc, + CXXScopeSpec &ReductionOrMapperIdScopeSpec, + DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, - ArrayRef<SourceLocation> MapTypeModifiersLoc, - OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, - SourceLocation DepLinMapLoc); + ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, + bool IsMapTypeImplicit, SourceLocation DepLinMapLoc); + /// Called on well-formed 'allocate' clause. + OMPClause * + ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList, + SourceLocation StartLoc, SourceLocation ColonLoc, + SourceLocation LParenLoc, SourceLocation EndLoc); /// Called on well-formed 'private' clause. OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, @@ -9339,10 +9690,12 @@ public: OMPClause * ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, ArrayRef<SourceLocation> MapTypeModifiersLoc, + CXXScopeSpec &MapperIdScopeSpec, + DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, - ArrayRef<Expr *> VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc); + ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, + ArrayRef<Expr *> UnresolvedMappers = llvm::None); /// Called on well-formed 'num_teams' clause. OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -9367,25 +9720,22 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc); /// Called on well-formed 'to' clause. - OMPClause *ActOnOpenMPToClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); + OMPClause * + ActOnOpenMPToClause(ArrayRef<Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec, + DeclarationNameInfo &MapperId, + const OMPVarListLocTy &Locs, + ArrayRef<Expr *> UnresolvedMappers = llvm::None); /// Called on well-formed 'from' clause. - OMPClause *ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); + OMPClause *ActOnOpenMPFromClause( + ArrayRef<Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec, + DeclarationNameInfo &MapperId, const OMPVarListLocTy &Locs, + ArrayRef<Expr *> UnresolvedMappers = llvm::None); /// Called on well-formed 'use_device_ptr' clause. OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); + const OMPVarListLocTy &Locs); /// Called on well-formed 'is_device_ptr' clause. OMPClause *ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); + const OMPVarListLocTy &Locs); /// The kind of conversion being performed. enum CheckedConversionKind { @@ -9554,6 +9904,12 @@ public: /// like address spaces. IncompatiblePointerDiscardsQualifiers, + /// IncompatibleNestedPointerAddressSpaceMismatch - The assignment + /// changes address spaces in nested pointer types which is not allowed. + /// For instance, converting __private int ** to __generic int ** is + /// illegal even though __private could be converted to __generic. + IncompatibleNestedPointerAddressSpaceMismatch, + /// IncompatibleNestedPointerQualifiers - The assignment is between two /// nested pointer types, and the qualifiers other than the first two /// levels differ e.g. char ** -> const char **, but we accept them as an @@ -9949,6 +10305,14 @@ public: ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr = false); + /// ActOnExplicitBoolSpecifier - Build an ExplicitSpecifier from an expression + /// found in an explicit(bool) specifier. + ExplicitSpecifier ActOnExplicitBoolSpecifier(Expr *E); + + /// tryResolveExplicitSpecifier - Attempt to resolve the explict specifier. + /// Returns true if the explicit specifier is now resolved. + bool tryResolveExplicitSpecifier(ExplicitSpecifier &ExplicitSpec); + /// DiagnoseAssignmentAsCondition - Given that an expression is /// being used as a boolean condition, warn if it's an assignment. void DiagnoseAssignmentAsCondition(Expr *E); @@ -10024,7 +10388,7 @@ public: /// compilation, this is currently only enabled for CUDA compilations. llvm::DenseMap<CanonicalDeclPtr<FunctionDecl>, std::vector<PartialDiagnosticAt>> - CUDADeferredDiags; + DeviceDeferredDiags; /// A pair of a canonical FunctionDecl and a SourceLocation. When used as the /// key in a hashtable, both the FD and location are hashed. @@ -10045,21 +10409,22 @@ public: /// map. llvm::DenseMap</* Callee = */ CanonicalDeclPtr<FunctionDecl>, /* Caller = */ FunctionDeclAndLoc> - CUDAKnownEmittedFns; + DeviceKnownEmittedFns; - /// A partial call graph maintained during CUDA compilation to support - /// deferred diagnostics. + /// A partial call graph maintained during CUDA/OpenMP device code 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. + /// set and add those functions to DeviceKnownEmittedFns. llvm::DenseMap</* Caller = */ CanonicalDeclPtr<FunctionDecl>, /* Callees = */ llvm::MapVector<CanonicalDeclPtr<FunctionDecl>, SourceLocation>> - CUDACallGraph; + DeviceCallGraph; - /// Diagnostic builder for CUDA errors which may or may not be deferred. + /// Diagnostic builder for CUDA/OpenMP devices 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 @@ -10073,7 +10438,7 @@ public: /// 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 { + class DeviceDiagBuilder { public: enum Kind { /// Emit no diagnostics. @@ -10090,29 +10455,32 @@ public: K_Deferred }; - CUDADiagBuilder(Kind K, SourceLocation Loc, unsigned DiagID, - FunctionDecl *Fn, Sema &S); - ~CUDADiagBuilder(); + DeviceDiagBuilder(Kind K, SourceLocation Loc, unsigned DiagID, + FunctionDecl *Fn, Sema &S); + DeviceDiagBuilder(DeviceDiagBuilder &&D); + DeviceDiagBuilder(const DeviceDiagBuilder &) = default; + ~DeviceDiagBuilder(); /// 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) + /// if (DeviceDiagBuilder(...) << foo << bar) /// return ExprError(); /// /// But see CUDADiagIfDeviceCode() and CUDADiagIfHostCode() -- you probably - /// want to use these instead of creating a CUDADiagBuilder yourself. + /// want to use these instead of creating a DeviceDiagBuilder yourself. operator bool() const { return ImmediateDiag.hasValue(); } template <typename T> - friend const CUDADiagBuilder &operator<<(const CUDADiagBuilder &Diag, - const T &Value) { + friend const DeviceDiagBuilder &operator<<(const DeviceDiagBuilder &Diag, + const T &Value) { if (Diag.ImmediateDiag.hasValue()) *Diag.ImmediateDiag << Value; - else if (Diag.PartialDiag.hasValue()) - *Diag.PartialDiag << Value; + else if (Diag.PartialDiagId.hasValue()) + Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second + << Value; return Diag; } @@ -10126,10 +10494,18 @@ public: // 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; + llvm::Optional<unsigned> PartialDiagId; }; - /// Creates a CUDADiagBuilder that emits the diagnostic if the current context + /// Indicate that this function (and thus everything it transtively calls) + /// will be codegen'ed, and emit any deferred diagnostics on this function and + /// its (transitive) callees. + void markKnownEmitted( + Sema &S, FunctionDecl *OrigCaller, FunctionDecl *OrigCallee, + SourceLocation OrigLoc, + const llvm::function_ref<bool(Sema &, FunctionDecl *)> IsKnownEmitted); + + /// Creates a DeviceDiagBuilder that emits the diagnostic if the current context /// is "used as device code". /// /// - If CurContext is a __host__ function, does not emit any diagnostics. @@ -10145,13 +10521,32 @@ public: /// if (CUDADiagIfDeviceCode(Loc, diag::err_cuda_vla) << CurrentCUDATarget()) /// return ExprError(); /// // Otherwise, continue parsing as normal. - CUDADiagBuilder CUDADiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); + DeviceDiagBuilder CUDADiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); - /// Creates a CUDADiagBuilder that emits the diagnostic if the current context + /// Creates a DeviceDiagBuilder 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); + DeviceDiagBuilder CUDADiagIfHostCode(SourceLocation Loc, unsigned DiagID); + + /// Creates a DeviceDiagBuilder that emits the diagnostic if the current + /// context is "used as device code". + /// + /// - If CurContext is a `declare target` function or it is known that the + /// function is emitted for the device, emits the diagnostics immediately. + /// - If CurContext is a non-`declare target` 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 NVPTX device code. + /// if (diagIfOpenMPDeviceCode(Loc, diag::err_vla_unsupported)) + /// return ExprError(); + /// // Otherwise, continue parsing as normal. + DeviceDiagBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID); + + DeviceDiagBuilder targetDiag(SourceLocation Loc, unsigned DiagID); enum CUDAFunctionTarget { CFT_Device, @@ -10284,6 +10679,11 @@ public: /// Copies target attributes from the template TD to the function FD. void inheritCUDATargetAttrs(FunctionDecl *FD, const FunctionTemplateDecl &TD); + /// Returns the name of the launch configuration function. This is the name + /// of the function that will be called to configure kernel call, with the + /// parameters specified via <<<>>>. + std::string getCudaConfigureFuncName() const; + /// \name Code completion //@{ /// Describes the context in which code completion occurs. @@ -10342,11 +10742,14 @@ public: struct CodeCompleteExpressionData; void CodeCompleteExpression(Scope *S, const CodeCompleteExpressionData &Data); - void CodeCompleteExpression(Scope *S, QualType PreferredType); + void CodeCompleteExpression(Scope *S, QualType PreferredType, + bool IsParenthesized = false); void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase, SourceLocation OpLoc, bool IsArrow, - bool IsBaseExprStatement); - void CodeCompletePostfixExpression(Scope *S, ExprResult LHS); + bool IsBaseExprStatement, + QualType PreferredType); + void CodeCompletePostfixExpression(Scope *S, ExprResult LHS, + QualType PreferredType); void CodeCompleteTag(Scope *S, unsigned TagSpec); void CodeCompleteTypeQualifiers(DeclSpec &DS); void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, @@ -10368,12 +10771,10 @@ public: IdentifierInfo *II, SourceLocation OpenParLoc); void CodeCompleteInitializer(Scope *S, Decl *D); - void CodeCompleteReturn(Scope *S); void CodeCompleteAfterIf(Scope *S); - void CodeCompleteBinaryRHS(Scope *S, Expr *LHS, tok::TokenKind Op); - void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, - bool EnteringContext, QualType BaseType); + void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext, + QualType BaseType, QualType PreferredType); void CodeCompleteUsing(Scope *S); void CodeCompleteUsingDirective(Scope *S); void CodeCompleteNamespaceDecl(Scope *S); @@ -10498,6 +10899,7 @@ private: ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, CallExpr *TheCall); + void checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, CallExpr *TheCall); bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, unsigned MaxWidth); @@ -10551,6 +10953,7 @@ private: bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum, unsigned ExpectedFieldNum, bool AllowName); + bool SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall); public: enum FormatStringType { FST_Scanf, @@ -10773,9 +11176,6 @@ private: "there shouldn't be any pending delayed exception spec checks"); assert(S.DelayedEquivalentExceptionSpecChecks.empty() && "there shouldn't be any pending delayed exception spec checks"); - assert(S.DelayedDefaultedMemberExceptionSpecs.empty() && - "there shouldn't be any pending delayed defaulted member " - "exception specs"); assert(S.DelayedDllExportClasses.empty() && "there shouldn't be any pending delayed DLL export classes"); swapSavedState(); @@ -10787,8 +11187,6 @@ private: SavedOverridingExceptionSpecChecks; decltype(DelayedEquivalentExceptionSpecChecks) SavedEquivalentExceptionSpecChecks; - decltype(DelayedDefaultedMemberExceptionSpecs) - SavedDefaultedMemberExceptionSpecs; decltype(DelayedDllExportClasses) SavedDllExportClasses; void swapSavedState() { @@ -10796,8 +11194,6 @@ private: S.DelayedOverridingExceptionSpecChecks); SavedEquivalentExceptionSpecChecks.swap( S.DelayedEquivalentExceptionSpecChecks); - SavedDefaultedMemberExceptionSpecs.swap( - S.DelayedDefaultedMemberExceptionSpecs); SavedDllExportClasses.swap(S.DelayedDllExportClasses); } }; @@ -10847,6 +11243,15 @@ public: Expr *E, llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action); + + /// Describes the reason a calling convention specification was ignored, used + /// for diagnostics. + enum class CallingConventionIgnoredReason { + ForThisTarget = 0, + VariadicFunction, + ConstructorDestructor, + BuiltinFunction + }; }; /// RAII object that enters a new expression evaluation context. |