diff options
Diffstat (limited to 'include/clang/Sema')
| -rw-r--r-- | include/clang/Sema/AttributeList.h | 1 | ||||
| -rw-r--r-- | include/clang/Sema/DeclSpec.h | 63 | ||||
| -rw-r--r-- | include/clang/Sema/IdentifierResolver.h | 16 | ||||
| -rw-r--r-- | include/clang/Sema/Initialization.h | 40 | ||||
| -rw-r--r-- | include/clang/Sema/Lookup.h | 2 | ||||
| -rw-r--r-- | include/clang/Sema/MultiplexExternalSemaSource.h | 2 | ||||
| -rw-r--r-- | include/clang/Sema/Overload.h | 1 | ||||
| -rw-r--r-- | include/clang/Sema/Ownership.h | 1 | ||||
| -rw-r--r-- | include/clang/Sema/ScopeInfo.h | 81 | ||||
| -rw-r--r-- | include/clang/Sema/Sema.h | 369 | ||||
| -rw-r--r-- | include/clang/Sema/Template.h | 34 |
11 files changed, 434 insertions, 176 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index e74bf6a7cc86..7c1678086c2f 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -927,6 +927,7 @@ enum AttributeDeclKind { ExpectedStructClassVariableFunctionOrInlineNamespace, ExpectedForMaybeUnused, ExpectedEnumOrClass, + ExpectedNamedDecl, }; } // end namespace clang diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 331fd0db6724..df5e1050367e 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -519,7 +519,7 @@ public: SourceRange getTypeofParensRange() const { return TypeofParensRange; } void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } - bool containsPlaceholderType() const { + bool hasAutoTypeSpec() const { return (TypeSpecType == TST_auto || TypeSpecType == TST_auto_type || TypeSpecType == TST_decltype_auto); } @@ -819,7 +819,9 @@ public: : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr), Nullability(0), GetterName(nullptr), SetterName(nullptr) { } - ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; } + ObjCDeclQualifier getObjCDeclQualifier() const { + return (ObjCDeclQualifier)objcDeclQualifier; + } void setObjCDeclQualifier(ObjCDeclQualifier DQVal) { objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal); } @@ -859,17 +861,25 @@ public: const IdentifierInfo *getGetterName() const { return GetterName; } IdentifierInfo *getGetterName() { return GetterName; } - void setGetterName(IdentifierInfo *name) { GetterName = name; } + SourceLocation getGetterNameLoc() const { return GetterNameLoc; } + void setGetterName(IdentifierInfo *name, SourceLocation loc) { + GetterName = name; + GetterNameLoc = loc; + } const IdentifierInfo *getSetterName() const { return SetterName; } IdentifierInfo *getSetterName() { return SetterName; } - void setSetterName(IdentifierInfo *name) { SetterName = name; } + SourceLocation getSetterNameLoc() const { return SetterNameLoc; } + void setSetterName(IdentifierInfo *name, SourceLocation loc) { + SetterName = name; + SetterNameLoc = loc; + } private: // FIXME: These two are unrelated and mutually exclusive. So perhaps // we can put them in a union to reflect their mutual exclusivity // (space saving is negligible). - ObjCDeclQualifier objcDeclQualifier : 7; + unsigned objcDeclQualifier : 7; // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind unsigned PropertyAttributes : 15; @@ -880,6 +890,9 @@ private: IdentifierInfo *GetterName; // getter name or NULL if no getter IdentifierInfo *SetterName; // setter name or NULL if no setter + SourceLocation GetterNameLoc; // location of the getter attribute's value + SourceLocation SetterNameLoc; // location of the setter attribute's value + }; /// \brief Represents a C++ unqualified-id that has been parsed. @@ -908,7 +921,9 @@ public: /// \brief A template-id, e.g., f<int>. IK_TemplateId, /// \brief An implicit 'self' parameter - IK_ImplicitSelfParam + IK_ImplicitSelfParam, + /// \brief A deduction-guide name (a template-name) + IK_DeductionGuideName } Kind; struct OFI { @@ -928,8 +943,8 @@ public: /// \brief Anonymous union that holds extra data associated with the /// parsed unqualified-id. union { - /// \brief When Kind == IK_Identifier, the parsed identifier, or when Kind - /// == IK_UserLiteralId, the identifier suffix. + /// \brief When Kind == IK_Identifier, the parsed identifier, or when + /// Kind == IK_UserLiteralId, the identifier suffix. IdentifierInfo *Identifier; /// \brief When Kind == IK_OperatorFunctionId, the overloaded operator @@ -947,6 +962,9 @@ public: /// \brief When Kind == IK_DestructorName, the type referred to by the /// class-name. UnionParsedType DestructorName; + + /// \brief When Kind == IK_DeductionGuideName, the parsed template-name. + UnionParsedTemplateTy TemplateName; /// \brief When Kind == IK_TemplateId or IK_ConstructorTemplateId, /// the template-id annotation that contains the template name and @@ -1085,6 +1103,18 @@ public: /// \p TemplateId and will free it on destruction. void setTemplateId(TemplateIdAnnotation *TemplateId); + /// \brief Specify that this unqualified-id was parsed as a template-name for + /// a deduction-guide. + /// + /// \param Template The parsed template-name. + /// \param TemplateLoc The location of the parsed template-name. + void setDeductionGuideName(ParsedTemplateTy Template, + SourceLocation TemplateLoc) { + Kind = IK_DeductionGuideName; + TemplateName = Template; + StartLocation = EndLocation = TemplateLoc; + } + /// \brief Return the source range that covers this unqualified-id. SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(StartLocation, EndLocation); @@ -1709,6 +1739,7 @@ public: ObjCParameterContext,// An ObjC method parameter type. KNRTypeListContext, // K&R type definition list for formals. TypeNameContext, // Abstract declarator for types. + FunctionalCastContext, // Type in a C++ functional cast expression. MemberContext, // Struct/Union field. BlockContext, // Declaration within a block in a function. ForContext, // Declaration within first part of a for loop. @@ -1911,6 +1942,7 @@ public: return false; case TypeNameContext: + case FunctionalCastContext: case AliasDeclContext: case AliasTemplateContext: case PrototypeContext: @@ -1951,6 +1983,7 @@ public: return true; case TypeNameContext: + case FunctionalCastContext: case CXXNewContext: case AliasDeclContext: case AliasTemplateContext: @@ -1983,6 +2016,7 @@ public: case CXXCatchContext: case ObjCCatchContext: case TypeNameContext: + case FunctionalCastContext: case ConversionIdContext: case ObjCParameterContext: case ObjCResultContext: @@ -2021,6 +2055,7 @@ public: // These contexts don't allow any kind of non-abstract declarator. case KNRTypeListContext: case TypeNameContext: + case FunctionalCastContext: case AliasDeclContext: case AliasTemplateContext: case LambdaExprParameterContext: @@ -2078,6 +2113,7 @@ public: case CXXCatchContext: case ObjCCatchContext: case TypeNameContext: + case FunctionalCastContext: // FIXME case CXXNewContext: case AliasDeclContext: case AliasTemplateContext: @@ -2279,6 +2315,7 @@ public: case ConditionContext: case KNRTypeListContext: case TypeNameContext: + case FunctionalCastContext: case AliasDeclContext: case AliasTemplateContext: case PrototypeContext: @@ -2312,6 +2349,16 @@ public: return true; } + /// \brief Determine whether a trailing return type was written (at any + /// level) within this declarator. + bool hasTrailingReturnType() const { + for (const auto &Chunk : type_objects()) + if (Chunk.Kind == DeclaratorChunk::Function && + Chunk.Fun.hasTrailingReturnType()) + return true; + return false; + } + /// takeAttributes - Takes attributes from the given parsed-attributes /// set and add them to this declarator. /// diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h index a07834f95629..382fe80bea7d 100644 --- a/include/clang/Sema/IdentifierResolver.h +++ b/include/clang/Sema/IdentifierResolver.h @@ -73,12 +73,10 @@ public: typedef std::input_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; - /// Ptr - There are 3 forms that 'Ptr' represents: + /// Ptr - There are 2 forms that 'Ptr' represents: /// 1) A single NamedDecl. (Ptr & 0x1 == 0) /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the - /// same declaration context. (Ptr & 0x3 == 0x1) - /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent - /// declaration contexts too. (Ptr & 0x3 == 0x3) + /// same declaration context. (Ptr & 0x1 == 0x1) uintptr_t Ptr; typedef IdDeclInfo::DeclsTy::iterator BaseIter; @@ -97,7 +95,7 @@ public: BaseIter getIterator() const { assert(isIterator() && "Ptr not an iterator!"); - return reinterpret_cast<BaseIter>(Ptr & ~0x3); + return reinterpret_cast<BaseIter>(Ptr & ~0x1); } friend class IdentifierResolver; @@ -128,14 +126,6 @@ public: incrementSlowCase(); return *this; } - - uintptr_t getAsOpaqueValue() const { return Ptr; } - - static iterator getFromOpaqueValue(uintptr_t P) { - iterator Result; - Result.Ptr = P; - return Result; - } }; /// begin - Returns an iterator for decls with the name 'Name'. diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 94be58ac8aeb..bd07b9ea9aee 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -70,6 +70,9 @@ public: /// \brief The entity being initialized is a field of block descriptor for /// the copied-in c++ object. EK_BlockElement, + /// The entity being initialized is a field of block descriptor for the + /// copied-in lambda object that's used in the lambda to block conversion. + EK_LambdaToBlockConversionBlockElement, /// \brief The entity being initialized is the real or imaginary part of a /// complex number. EK_ComplexElement, @@ -260,7 +263,13 @@ public: QualType Type, bool NRVO) { return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO); } - + + static InitializedEntity InitializeLambdaToBlock(SourceLocation BlockVarLoc, + QualType Type, bool NRVO) { + return InitializedEntity(EK_LambdaToBlockConversionBlockElement, + BlockVarLoc, Type, NRVO); + } + /// \brief Create the initialization entity for an exception object. static InitializedEntity InitializeException(SourceLocation ThrowLoc, QualType Type, bool NRVO) { @@ -274,15 +283,18 @@ public: /// \brief Create the initialization entity for a temporary. static InitializedEntity InitializeTemporary(QualType Type) { - InitializedEntity Result(EK_Temporary, SourceLocation(), Type); - Result.TypeInfo = nullptr; - return Result; + return InitializeTemporary(nullptr, Type); } /// \brief Create the initialization entity for a temporary. static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo) { - InitializedEntity Result(EK_Temporary, SourceLocation(), - TypeInfo->getType()); + return InitializeTemporary(TypeInfo, TypeInfo->getType()); + } + + /// \brief Create the initialization entity for a temporary. + static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo, + QualType Type) { + InitializedEntity Result(EK_Temporary, SourceLocation(), Type); Result.TypeInfo = TypeInfo; return Result; } @@ -579,6 +591,16 @@ public: return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal, InitLoc, LParenLoc, RParenLoc); } + + /// \brief Create an initialization from an initializer (which, for direct + /// initialization from a parenthesized list, will be a ParenListExpr). + static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit, + Expr *Init) { + if (!Init) return CreateDefault(Loc); + if (!DirectInit) return CreateCopy(Loc, Init->getLocStart()); + if (isa<InitListExpr>(Init)) return CreateDirectList(Loc); + return CreateDirect(Loc, Init->getLocStart(), Init->getLocEnd()); + } /// \brief Determine the initialization kind. InitKind getKind() const { @@ -809,6 +831,8 @@ public: enum FailureKind { /// \brief Too many initializers provided for a reference. FK_TooManyInitsForReference, + /// \brief Reference initialized from a parenthesized initializer list. + FK_ParenthesizedListInitForReference, /// \brief Array must be initialized with an initializer list. FK_ArrayNeedsInitList, /// \brief Array must be initialized with an initializer list or a @@ -853,6 +877,8 @@ public: FK_ConversionFromPropertyFailed, /// \brief Too many initializers for scalar FK_TooManyInitsForScalar, + /// \brief Scalar initialized from a parenthesized initializer list. + FK_ParenthesizedListInitForScalar, /// \brief Reference initialization from an initializer list FK_ReferenceBindingToInitList, /// \brief Initialization of some unused destination type with an @@ -879,7 +905,7 @@ public: /// having its address taken. FK_AddressOfUnaddressableFunction, /// \brief List-copy-initialization chose an explicit constructor. - FK_ExplicitConstructor + FK_ExplicitConstructor, }; private: diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index 2ed9548b5936..9134ddf9198c 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -146,7 +146,7 @@ public: } // TODO: consider whether this constructor should be restricted to take - // as input a const IndentifierInfo* (instead of Name), + // as input a const IdentifierInfo* (instead of Name), // forcing other cases towards the constructor taking a DNInfo. LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc, Sema::LookupNameKind LookupKind, diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h index 37157204ea10..1d681a00552f 100644 --- a/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/include/clang/Sema/MultiplexExternalSemaSource.h @@ -90,6 +90,8 @@ public: /// initializers themselves. CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override; + ExtKind hasExternalDefinitions(const Decl *D) override; + /// \brief Find all declarations with the given name in the /// given context. bool FindExternalVisibleDeclsByName(const DeclContext *DC, diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 5220d9873022..941b772b7880 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -98,6 +98,7 @@ namespace clang { ICR_Exact_Match = 0, ///< Exact Match ICR_Promotion, ///< Promotion ICR_Conversion, ///< Conversion + ICR_OCL_Scalar_Widening, ///< OpenCL Scalar Widening ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion ICR_Writeback_Conversion, ///< ObjC ARC writeback conversion ICR_C_Conversion, ///< Conversion only allowed in the C standard. diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h index fd46de870fb4..848837a1decc 100644 --- a/include/clang/Sema/Ownership.h +++ b/include/clang/Sema/Ownership.h @@ -257,6 +257,7 @@ namespace clang { typedef ActionResult<Decl*> DeclResult; typedef OpaquePtr<TemplateName> ParsedTemplateTy; + typedef UnionOpaquePtr<TemplateName> UnionParsedTemplateTy; typedef MutableArrayRef<Expr*> MultiExprArg; typedef MutableArrayRef<Stmt*> MultiStmtArg; diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index 4b54807ab660..4487c7c2ccb6 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -24,6 +24,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringSwitch.h" #include <algorithm> namespace clang { @@ -135,6 +136,18 @@ public: /// false if there is an invocation of an initializer on 'self'. bool ObjCWarnForNoInitDelegation : 1; + /// \brief True only when this function has not already built, or attempted + /// to build, the initial and final coroutine suspend points + bool NeedsCoroutineSuspends : 1; + + /// \brief An enumeration represeting the kind of the first coroutine statement + /// in the function. One of co_return, co_await, or co_yield. + unsigned char FirstCoroutineStmtKind : 2; + + /// First coroutine statement in the current function. + /// (ex co_return, co_await, co_yield) + SourceLocation FirstCoroutineStmtLoc; + /// First 'return' statement in the current function. SourceLocation FirstReturnLoc; @@ -157,12 +170,10 @@ public: SmallVector<ReturnStmt*, 4> Returns; /// \brief The promise object for this coroutine, if any. - VarDecl *CoroutinePromise; + VarDecl *CoroutinePromise = nullptr; - /// \brief The list of coroutine control flow constructs (co_await, co_yield, - /// co_return) that occur within the function or block. Empty if and only if - /// this function or block is not (yet known to be) a coroutine. - SmallVector<Stmt*, 4> CoroutineStmts; + /// \brief The initial and final coroutine suspend points. + std::pair<Stmt *, Stmt *> CoroutineSuspends; /// \brief The stack of currently active compound stamement scopes in the /// function. @@ -376,7 +387,47 @@ public: (HasIndirectGoto || (HasBranchProtectedScope && HasBranchIntoScope)); } - + + void setFirstCoroutineStmt(SourceLocation Loc, StringRef Keyword) { + assert(FirstCoroutineStmtLoc.isInvalid() && + "first coroutine statement location already set"); + FirstCoroutineStmtLoc = Loc; + FirstCoroutineStmtKind = llvm::StringSwitch<unsigned char>(Keyword) + .Case("co_return", 0) + .Case("co_await", 1) + .Case("co_yield", 2); + } + + StringRef getFirstCoroutineStmtKeyword() const { + assert(FirstCoroutineStmtLoc.isValid() + && "no coroutine statement available"); + switch (FirstCoroutineStmtKind) { + case 0: return "co_return"; + case 1: return "co_await"; + case 2: return "co_yield"; + default: + llvm_unreachable("FirstCoroutineStmtKind has an invalid value"); + }; + } + + void setNeedsCoroutineSuspends(bool value = true) { + assert((!value || CoroutineSuspends.first == nullptr) && + "we already have valid suspend points"); + NeedsCoroutineSuspends = value; + } + + bool hasInvalidCoroutineSuspends() const { + return !NeedsCoroutineSuspends && CoroutineSuspends.first == nullptr; + } + + void setCoroutineSuspends(Stmt *Initial, Stmt *Final) { + assert(Initial && Final && "suspend points cannot be null"); + assert(CoroutineSuspends.first == nullptr && "suspend points already set"); + NeedsCoroutineSuspends = false; + CoroutineSuspends.first = Initial; + CoroutineSuspends.second = Final; + } + FunctionScopeInfo(DiagnosticsEngine &Diag) : Kind(SK_Function), HasBranchProtectedScope(false), @@ -391,6 +442,7 @@ public: ObjCWarnForNoDesignatedInitChain(false), ObjCIsSecondaryInit(false), ObjCWarnForNoInitDelegation(false), + NeedsCoroutineSuspends(true), ErrorTrap(Diag) { } virtual ~FunctionScopeInfo(); @@ -452,6 +504,14 @@ public: /// non-static data member that would hold the capture. QualType CaptureType; + /// \brief Whether an explicit capture has been odr-used in the body of the + /// lambda. + bool ODRUsed; + + /// \brief Whether an explicit capture has been non-odr-used in the body of + /// the lambda. + bool NonODRUsed; + public: Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, SourceLocation Loc, SourceLocation EllipsisLoc, @@ -460,7 +520,8 @@ public: InitExprAndCaptureKind( Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef : Cap_ByCopy), - Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {} + Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType), + ODRUsed(false), NonODRUsed(false) {} enum IsThisCapture { ThisCapture }; Capture(IsThisCapture, bool IsNested, SourceLocation Loc, @@ -468,7 +529,8 @@ public: : VarAndNestedAndThis( nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))), InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef), - Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {} + Loc(Loc), EllipsisLoc(), CaptureType(CaptureType), ODRUsed(false), + NonODRUsed(false) {} bool isThisCapture() const { return VarAndNestedAndThis.getInt() & IsThisCaptured; @@ -491,6 +553,9 @@ public: bool isNested() const { return VarAndNestedAndThis.getInt() & IsNestedCapture; } + bool isODRUsed() const { return ODRUsed; } + bool isNonODRUsed() const { return NonODRUsed; } + void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; } VarDecl *getVariable() const { return VarAndNestedAndThis.getPointer(); diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 63d078498fe4..5a3cdfb77c9c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -26,6 +26,7 @@ #include "clang/AST/MangleNumberingContext.h" #include "clang/AST/NSAPI.h" #include "clang/AST/PrettyPrinter.h" +#include "clang/AST/StmtCXX.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeOrdering.h" #include "clang/Basic/ExpressionTraits.h" @@ -101,6 +102,7 @@ namespace clang { class CodeCompletionAllocator; class CodeCompletionTUInfo; class CodeCompletionResult; + class CoroutineBodyStmt; class Decl; class DeclAccessPair; class DeclContext; @@ -679,7 +681,8 @@ public: : S(S), SavedContext(S, DC) { S.PushFunctionScope(); - S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); + S.PushExpressionEvaluationContext( + Sema::ExpressionEvaluationContext::PotentiallyEvaluated); } ~SynthesizedFunctionScope() { @@ -800,7 +803,7 @@ public: /// \brief Describes how the expressions currently being parsed are /// evaluated at run-time, if at all. - enum ExpressionEvaluationContext { + enum class ExpressionEvaluationContext { /// \brief The current expression and its subexpressions occur within an /// unevaluated operand (C++11 [expr]p7), such as the subexpression of /// \c sizeof, where the type of the expression may be significant but @@ -906,8 +909,12 @@ public: MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx); bool isUnevaluated() const { - return Context == Unevaluated || Context == UnevaluatedAbstract || - Context == UnevaluatedList; + return Context == ExpressionEvaluationContext::Unevaluated || + Context == ExpressionEvaluationContext::UnevaluatedAbstract || + Context == ExpressionEvaluationContext::UnevaluatedList; + } + bool isConstantEvaluated() const { + return Context == ExpressionEvaluationContext::ConstantEvaluated; } }; @@ -931,7 +938,7 @@ public: /// /// This is basically a wrapper around PointerIntPair. The lowest bits of the /// integer are used to determine whether overload resolution succeeded. - class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode { + class SpecialMemberOverloadResult { public: enum Kind { NoMemberOrDeleted, @@ -943,9 +950,9 @@ public: llvm::PointerIntPair<CXXMethodDecl*, 2> Pair; public: - SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID) - : FastFoldingSetNode(ID) - {} + SpecialMemberOverloadResult() : Pair() {} + SpecialMemberOverloadResult(CXXMethodDecl *MD) + : Pair(MD, MD->isDeleted() ? NoMemberOrDeleted : Success) {} CXXMethodDecl *getMethod() const { return Pair.getPointer(); } void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); } @@ -954,9 +961,18 @@ public: void setKind(Kind K) { Pair.setInt(K); } }; + class SpecialMemberOverloadResultEntry + : public llvm::FastFoldingSetNode, + public SpecialMemberOverloadResult { + public: + SpecialMemberOverloadResultEntry(const llvm::FoldingSetNodeID &ID) + : FastFoldingSetNode(ID) + {} + }; + /// \brief A cache of special member function overload resolution results /// for C++ records. - llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache; + llvm::FoldingSet<SpecialMemberOverloadResultEntry> SpecialMemberCache; /// \brief A cache of the flags available in enumerations with the flag_bits /// attribute. @@ -1054,14 +1070,12 @@ public: /// statements. class FPContractStateRAII { public: - FPContractStateRAII(Sema& S) - : S(S), OldFPContractState(S.FPFeatures.fp_contract) {} - ~FPContractStateRAII() { - S.FPFeatures.fp_contract = OldFPContractState; - } + FPContractStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.FPFeatures) {} + ~FPContractStateRAII() { S.FPFeatures = OldFPFeaturesState; } + private: Sema& S; - bool OldFPContractState : 1; + FPOptions OldFPFeaturesState; }; void addImplicitTypedef(StringRef Name, QualType T); @@ -1235,9 +1249,11 @@ public: sema::BlockScopeInfo *getCurBlock(); /// Retrieve the current lambda scope info, if any. - /// \param IgnoreCapturedRegions true if should find the top-most lambda scope - /// info ignoring all inner captured regions scope infos. - sema::LambdaScopeInfo *getCurLambda(bool IgnoreCapturedRegions = false); + /// \param IgnoreNonLambdaCapturingScope true if should find the top-most + /// lambda scope info ignoring all inner capturing scopes that are not + /// lambda scopes. + sema::LambdaScopeInfo * + getCurLambda(bool IgnoreNonLambdaCapturingScope = false); /// \brief Retrieve the current generic lambda info, if any. sema::LambdaScopeInfo *getCurGenericLambda(); @@ -1548,6 +1564,7 @@ public: ParsedType ObjectType = nullptr, bool IsCtorOrDtorName = false, bool WantNontrivialTypeSourceInfo = false, + bool IsClassTemplateDeductionContext = true, IdentifierInfo **CorrectedII = nullptr); TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S); @@ -1689,6 +1706,18 @@ public: bool IsAddressOfOperand, std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr); + /// Describes the detailed kind of a template name. Used in diagnostics. + enum class TemplateNameKindForDiagnostics { + ClassTemplate, + FunctionTemplate, + VarTemplate, + AliasTemplate, + TemplateTemplateParam, + DependentTemplate + }; + TemplateNameKindForDiagnostics + getTemplateNameKindForDiagnostics(TemplateName Name); + Decl *ActOnDeclarator(Scope *S, Declarator &D); NamedDecl *HandleDeclarator(Scope *S, Declarator &D, @@ -1709,8 +1738,11 @@ public: static bool adjustContextForLocalExternDecl(DeclContext *&DC); void DiagnoseFunctionSpecifiers(const DeclSpec &DS); + NamedDecl *getShadowedDeclaration(const TypedefNameDecl *D, + const LookupResult &R); NamedDecl *getShadowedDeclaration(const VarDecl *D, const LookupResult &R); - void CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl, const LookupResult &R); + void CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl, + const LookupResult &R); void CheckShadow(Scope *S, VarDecl *D); /// Warn if 'E', which is an expression that is about to be modified, refers @@ -1747,6 +1779,8 @@ public: // Returns true if the variable declaration is a redeclaration bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); void CheckVariableDeclarationType(VarDecl *NewVD); + bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, + Expr *Init); void CheckCompleteVariableDeclaration(VarDecl *VD); void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD); void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); @@ -1769,7 +1803,7 @@ public: // Returns true if the function declaration is a redeclaration bool CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, LookupResult &Previous, - bool IsExplicitSpecialization); + bool IsMemberSpecialization); bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl); void CheckMain(FunctionDecl *FD, const DeclSpec &D); void CheckMSVCRTEntryPoint(FunctionDecl *FD); @@ -1794,7 +1828,6 @@ public: void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit); void ActOnUninitializedDecl(Decl *dcl); void ActOnInitializerError(Decl *Dcl); - bool canInitializeWithParenthesizedList(QualType TargetType); void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc); void ActOnCXXForRangeDecl(Decl *D); @@ -2876,13 +2909,13 @@ public: LOLR_StringTemplate }; - SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D, - CXXSpecialMember SM, - bool ConstArg, - bool VolatileArg, - bool RValueThis, - bool ConstThis, - bool VolatileThis); + SpecialMemberOverloadResult LookupSpecialMember(CXXRecordDecl *D, + CXXSpecialMember SM, + bool ConstArg, + bool VolatileArg, + bool RValueThis, + bool ConstThis, + bool VolatileThis); typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator; typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)> @@ -2963,9 +2996,6 @@ public: void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, QualType T1, QualType T2, UnresolvedSetImpl &Functions); - void addOverloadedOperatorToUnresolvedSet(UnresolvedSetImpl &Functions, - DeclAccessPair Operator, - QualType T1, QualType T2); LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, SourceLocation GnuLabelLoc = SourceLocation()); @@ -3098,6 +3128,8 @@ public: void ProcessPragmaWeak(Scope *S, Decl *D); // Decl attributes - this routine is the top level dispatcher. void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD); + // Helper for delayed proccessing of attributes. + void ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList); void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL, bool IncludeCXX11Attributes = true); bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, @@ -3184,7 +3216,6 @@ public: bool IsProtocolMethodDecl); typedef llvm::SmallPtrSet<Selector, 8> SelectorSet; - typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap; /// CheckImplementationIvars - This routine checks if the instance variables /// listed in the implelementation match those listed in the interface. @@ -3237,7 +3268,9 @@ public: SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, + SourceLocation GetterNameLoc, Selector SetterSel, + SourceLocation SetterNameLoc, const bool isReadWrite, unsigned &Attributes, const unsigned AttributesAsWritten, @@ -3253,7 +3286,9 @@ public: SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, + SourceLocation GetterNameLoc, Selector SetterSel, + SourceLocation SetterNameLoc, const bool isReadWrite, const unsigned Attributes, const unsigned AttributesAsWritten, @@ -4328,7 +4363,7 @@ public: /// \brief Determine whether Ctor is an initializer-list constructor, as /// defined in [dcl.init.list]p2. - bool isInitListConstructor(const CXXConstructorDecl *Ctor); + bool isInitListConstructor(const FunctionDecl *Ctor); Decl *ActOnUsingDirective(Scope *CurScope, SourceLocation UsingLoc, @@ -4737,7 +4772,8 @@ public: ParsedType ObjectType, bool EnteringContext); - ParsedType getDestructorType(const DeclSpec& DS, ParsedType ObjectType); + ParsedType getDestructorTypeForDecltype(const DeclSpec &DS, + ParsedType ObjectType); // Checks that reinterpret casts don't have undefined behavior. void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, @@ -4953,7 +4989,7 @@ public: ArrayRef<TypeSourceInfo *> Args, SourceLocation RParenLoc); - /// ActOnArrayTypeTrait - Parsed one of the bianry type trait support + /// ActOnArrayTypeTrait - Parsed one of the binary type trait support /// pseudo-functions. ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, @@ -5106,7 +5142,8 @@ public: CXXScopeSpec &SS, NamedDecl *ScopeLookupResult, bool ErrorRecoveryLookup, - bool *IsCorrectedToColon = nullptr); + bool *IsCorrectedToColon = nullptr, + bool OnlyNamespace = false); /// \brief The parser has parsed a nested-name-specifier 'identifier::'. /// @@ -5130,13 +5167,16 @@ public: /// are allowed. The bool value pointed by this parameter is set to 'true' /// if the identifier is treated as if it was followed by ':', not '::'. /// + /// \param OnlyNamespace If true, only considers namespaces in lookup. + /// /// \returns true if an error occurred, false otherwise. bool ActOnCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, bool EnteringContext, CXXScopeSpec &SS, bool ErrorRecoveryLookup = false, - bool *IsCorrectedToColon = nullptr); + bool *IsCorrectedToColon = nullptr, + bool OnlyNamespace = false); ExprResult ActOnDecltypeExpression(Expr *E); @@ -5312,6 +5352,12 @@ public: ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, Scope *CurScope); + /// \brief Does copying/destroying the captured variable have side effects? + bool CaptureHasSideEffects(const sema::LambdaScopeInfo::Capture &From); + + /// \brief Diagnose if an explicit lambda capture is unused. + void DiagnoseUnusedLambdaCapture(const sema::LambdaScopeInfo::Capture &From); + /// \brief Complete a lambda-expression having processed and attached the /// lambda body. ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, @@ -5604,6 +5650,9 @@ public: void CheckConversionDeclarator(Declarator &D, QualType &R, StorageClass& SC); Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion); + void CheckDeductionGuideDeclarator(Declarator &D, QualType &R, + StorageClass &SC); + void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD); void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD); void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD, @@ -5807,6 +5856,12 @@ public: TemplateTy &Template, bool &MemberOfUnknownSpecialization); + /// Determine whether a particular identifier might be the name in a C++1z + /// deduction-guide declaration. + bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, + SourceLocation NameLoc, + ParsedTemplateTy *Template = nullptr); + bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, SourceLocation IILoc, Scope *S, @@ -5882,7 +5937,7 @@ public: SourceLocation DeclStartLoc, SourceLocation DeclLoc, const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId, ArrayRef<TemplateParameterList *> ParamLists, - bool IsFriend, bool &IsExplicitSpecialization, bool &Invalid); + bool IsFriend, bool &IsMemberSpecialization, bool &Invalid); DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, @@ -5911,11 +5966,13 @@ public: TypeResult ActOnTemplateIdType(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, - TemplateTy Template, SourceLocation TemplateLoc, + TemplateTy Template, IdentifierInfo *TemplateII, + SourceLocation TemplateIILoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, - bool IsCtorOrDtorName = false); + bool IsCtorOrDtorName = false, + bool IsClassName = false); /// \brief Parsed an elaborated-type-specifier that refers to a template-id, /// such as \c class T::template apply<U>. @@ -5957,13 +6014,10 @@ public: const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs); - TemplateNameKind ActOnDependentTemplateName(Scope *S, - CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - UnqualifiedId &Name, - ParsedType ObjectType, - bool EnteringContext, - TemplateTy &Template); + TemplateNameKind ActOnDependentTemplateName( + Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, + UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, + TemplateTy &Template, bool AllowInjectedClassName = false); DeclResult ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK, @@ -6088,12 +6142,17 @@ public: /// \param Converted Will receive the converted, canonicalized template /// arguments. /// + /// \param UpdateArgsWithConversions If \c true, update \p TemplateArgs to + /// contain the converted forms of the template arguments as written. + /// Otherwise, \p TemplateArgs will not be modified. + /// /// \returns true if an error occurred, false otherwise. bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, - SmallVectorImpl<TemplateArgument> &Converted); + SmallVectorImpl<TemplateArgument> &Converted, + bool UpdateArgsWithConversions = true); bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg, @@ -6182,7 +6241,8 @@ public: /// \param SS the nested-name-specifier following the typename (e.g., 'T::'). /// \param TemplateLoc the location of the 'template' keyword, if any. /// \param TemplateName The template name. - /// \param TemplateNameLoc The location of the template name. + /// \param TemplateII The identifier used to name the template. + /// \param TemplateIILoc The location of the template name. /// \param LAngleLoc The location of the opening angle bracket ('<'). /// \param TemplateArgs The template arguments. /// \param RAngleLoc The location of the closing angle bracket ('>'). @@ -6191,7 +6251,8 @@ public: const CXXScopeSpec &SS, SourceLocation TemplateLoc, TemplateTy TemplateName, - SourceLocation TemplateNameLoc, + IdentifierInfo *TemplateII, + SourceLocation TemplateIILoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc); @@ -6706,6 +6767,9 @@ public: /// \brief Substitute Replacement for auto in TypeWithAuto TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement); + /// \brief Completely replace the \c auto in \p TypeWithAuto by + /// \p Replacement. This does not retain any \c auto type sugar. + QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement); /// \brief Result type of DeduceAutoType. enum DeduceAutoResult { @@ -6724,6 +6788,15 @@ public: bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose = true); + /// \brief Declare implicit deduction guides for a class template if we've + /// not already done so. + void DeclareImplicitDeductionGuides(TemplateDecl *Template, + SourceLocation Loc); + + QualType DeduceTemplateSpecializationFromInitializer( + TypeSourceInfo *TInfo, const InitializedEntity &Entity, + const InitializationKind &Kind, MultiExprArg Init); + QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, QualType Type, TypeSourceInfo *TSI, SourceRange Range, bool DirectInit, @@ -6792,10 +6865,12 @@ public: bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr); - /// \brief A template instantiation that is currently in progress. - struct ActiveTemplateInstantiation { + /// A context in which code is being synthesized (where a source location + /// alone is not sufficient to identify the context). This covers template + /// instantiation and various forms of implicitly-generated functions. + struct CodeSynthesisContext { /// \brief The kind of template instantiation we are performing - enum InstantiationKind { + enum SynthesisKind { /// We are instantiating a template declaration. The entity is /// the declaration we're instantiating (e.g., a CXXRecordDecl). TemplateInstantiation, @@ -6834,28 +6909,42 @@ public: /// We are instantiating the exception specification for a function /// template which was deferred until it was needed. - ExceptionSpecInstantiation + ExceptionSpecInstantiation, + + /// We are declaring an implicit special member function. + DeclaringSpecialMember, } Kind; - /// \brief The point of instantiation within the source code. + /// \brief Was the enclosing context a non-instantiation SFINAE context? + bool SavedInNonInstantiationSFINAEContext; + + /// \brief The point of instantiation or synthesis within the source code. SourceLocation PointOfInstantiation; + /// \brief The entity that is being synthesized. + Decl *Entity; + /// \brief The template (or partial specialization) in which we are /// performing the instantiation, for substitutions of prior template /// arguments. NamedDecl *Template; - /// \brief The entity that is being instantiated. - Decl *Entity; - /// \brief The list of template arguments we are substituting, if they /// are not part of the entity. const TemplateArgument *TemplateArgs; - /// \brief The number of template arguments in TemplateArgs. - unsigned NumTemplateArgs; + // FIXME: Wrap this union around more members, or perhaps store the + // kind-specific members in the RAII object owning the context. + union { + /// \brief The number of template arguments in TemplateArgs. + unsigned NumTemplateArgs; + + /// \brief The special member being declared or defined. + CXXSpecialMember SpecialMember; + }; ArrayRef<TemplateArgument> template_arguments() const { + assert(Kind != DeclaringSpecialMember); return {TemplateArgs, NumTemplateArgs}; } @@ -6868,56 +6957,20 @@ public: /// template instantiation. SourceRange InstantiationRange; - ActiveTemplateInstantiation() - : Kind(TemplateInstantiation), Template(nullptr), Entity(nullptr), + CodeSynthesisContext() + : Kind(TemplateInstantiation), Entity(nullptr), Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {} /// \brief Determines whether this template is an actual instantiation /// that should be counted toward the maximum instantiation depth. bool isInstantiationRecord() const; - - friend bool operator==(const ActiveTemplateInstantiation &X, - const ActiveTemplateInstantiation &Y) { - if (X.Kind != Y.Kind) - return false; - - if (X.Entity != Y.Entity) - return false; - - switch (X.Kind) { - case TemplateInstantiation: - case ExceptionSpecInstantiation: - return true; - - case PriorTemplateArgumentSubstitution: - case DefaultTemplateArgumentChecking: - return X.Template == Y.Template && X.TemplateArgs == Y.TemplateArgs; - - case DefaultTemplateArgumentInstantiation: - case ExplicitTemplateArgumentSubstitution: - case DeducedTemplateArgumentSubstitution: - case DefaultFunctionArgumentInstantiation: - return X.TemplateArgs == Y.TemplateArgs; - - } - - llvm_unreachable("Invalid InstantiationKind!"); - } - - friend bool operator!=(const ActiveTemplateInstantiation &X, - const ActiveTemplateInstantiation &Y) { - return !(X == Y); - } }; - /// \brief List of active template instantiations. + /// \brief List of active code synthesis contexts. /// - /// This vector is treated as a stack. As one template instantiation - /// requires another template instantiation, additional - /// instantiations are pushed onto the stack up to a - /// user-configurable limit LangOptions::InstantiationDepth. - SmallVector<ActiveTemplateInstantiation, 16> - ActiveTemplateInstantiations; + /// This vector is treated as a stack. As synthesis of one entity requires + /// synthesis of another, additional contexts are pushed onto the stack. + SmallVector<CodeSynthesisContext, 16> CodeSynthesisContexts; /// Specializations whose definitions are currently being instantiated. llvm::DenseSet<std::pair<Decl *, unsigned>> InstantiatingSpecializations; @@ -6928,7 +6981,7 @@ public: /// \brief Extra modules inspected when performing a lookup during a template /// instantiation. Computed lazily. - SmallVector<Module*, 16> ActiveTemplateInstantiationLookupModules; + SmallVector<Module*, 16> CodeSynthesisContextLookupModules; /// \brief Cache of additional modules that should be used for name lookup /// within the current template instantiation. Computed lazily; use @@ -6951,19 +7004,22 @@ public: /// of a template instantiation or template argument deduction. bool InNonInstantiationSFINAEContext; - /// \brief The number of ActiveTemplateInstantiation entries in - /// \c ActiveTemplateInstantiations that are not actual instantiations and, - /// therefore, should not be counted as part of the instantiation depth. + /// \brief The number of \p CodeSynthesisContexts that are not template + /// instantiations and, therefore, should not be counted as part of the + /// instantiation depth. + /// + /// When the instantiation depth reaches the user-configurable limit + /// \p LangOptions::InstantiationDepth we will abort instantiation. + // FIXME: Should we have a similar limit for other forms of synthesis? unsigned NonInstantiationEntries; - /// \brief The last template from which a template instantiation + /// \brief The depth of the context stack at the point when the most recent /// error or warning was produced. /// - /// This value is used to suppress printing of redundant template - /// instantiation backtraces when there are multiple errors in the - /// same instantiation. FIXME: Does this belong in Sema? It's tough - /// to implement it anywhere else. - ActiveTemplateInstantiation LastTemplateInstantiationErrorContext; + /// This value is used to suppress printing of redundant context stacks + /// when there are multiple errors or warnings in the same instantiation. + // FIXME: Does this belong in Sema? It's tough to implement it anywhere else. + unsigned LastEmittedCodeSynthesisContextDepth = 0; /// \brief The current index into pack expansion arguments that will be /// used for substitution of parameter packs. @@ -7041,7 +7097,7 @@ public: InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionTemplateDecl *FunctionTemplate, ArrayRef<TemplateArgument> TemplateArgs, - ActiveTemplateInstantiation::InstantiationKind Kind, + CodeSynthesisContext::SynthesisKind Kind, sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); @@ -7120,12 +7176,11 @@ public: Sema &SemaRef; bool Invalid; bool AlreadyInstantiating; - bool SavedInNonInstantiationSFINAEContext; bool CheckInstantiationDepth(SourceLocation PointOfInstantiation, SourceRange InstantiationRange); InstantiatingTemplate( - Sema &SemaRef, ActiveTemplateInstantiation::InstantiationKind Kind, + Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind, SourceLocation PointOfInstantiation, SourceRange InstantiationRange, Decl *Entity, NamedDecl *Template = nullptr, ArrayRef<TemplateArgument> TemplateArgs = None, @@ -7137,6 +7192,21 @@ public: operator=(const InstantiatingTemplate&) = delete; }; + void pushCodeSynthesisContext(CodeSynthesisContext Ctx); + void popCodeSynthesisContext(); + + /// Determine whether we are currently performing template instantiation. + bool inTemplateInstantiation() const { + return CodeSynthesisContexts.size() > NonInstantiationEntries; + } + + void PrintContextStack() { + if (!CodeSynthesisContexts.empty() && + CodeSynthesisContexts.size() != LastEmittedCodeSynthesisContextDepth) { + PrintInstantiationStack(); + LastEmittedCodeSynthesisContextDepth = CodeSynthesisContexts.size(); + } + } void PrintInstantiationStack(); /// \brief Determines whether we are currently in a context where @@ -7339,7 +7409,8 @@ public: TypeSourceInfo *SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, - SourceLocation Loc, DeclarationName Entity); + SourceLocation Loc, DeclarationName Entity, + bool AllowDeducedTST = false); QualType SubstType(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs, @@ -7436,6 +7507,12 @@ public: LateInstantiatedAttrVec *LateAttrs = nullptr, LocalInstantiationScope *OuterMostScope = nullptr); + void + InstantiateAttrsForDecl(const MultiLevelTemplateArgumentList &TemplateArgs, + const Decl *Pattern, Decl *Inst, + LateInstantiatedAttrVec *LateAttrs = nullptr, + LocalInstantiationScope *OuterMostScope = nullptr); + bool InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, @@ -7597,7 +7674,8 @@ public: Decl * const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, - SourceLocation EndProtoLoc); + SourceLocation EndProtoLoc, + AttributeList *AttrList); Decl *ActOnStartClassImplementation( SourceLocation AtClassImplLoc, @@ -8039,8 +8117,9 @@ public: SourceLocation AliasNameLoc); /// ActOnPragmaFPContract - Called on well formed - /// \#pragma {STDC,OPENCL} FP_CONTRACT - void ActOnPragmaFPContract(tok::OnOffSwitch OOS); + /// \#pragma {STDC,OPENCL} FP_CONTRACT and + /// \#pragma clang fp contract + void ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC); /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'. @@ -8103,6 +8182,11 @@ public: void AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, Expr *OE, unsigned SpellingListIndex); + /// AddAllocAlignAttr - Adds an alloc_align attribute to a particular + /// declaration. + void AddAllocAlignAttr(SourceRange AttrRange, Decl *D, Expr *ParamExpr, + unsigned SpellingListIndex); + /// AddAlignValueAttr - Adds an align_value attribute to a particular /// declaration. void AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E, @@ -8129,12 +8213,17 @@ public: // ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E); ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E); - StmtResult ActOnCoreturnStmt(SourceLocation KwLoc, Expr *E); + StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E); - ExprResult BuildCoawaitExpr(SourceLocation KwLoc, Expr *E); + ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *E, + bool IsImplicit = false); + ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *E, + UnresolvedLookupExpr* Lookup); ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E); - StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E); - + StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E, + bool IsImplicit = false); + StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs); + VarDecl *buildCoroutinePromise(SourceLocation Loc); void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body); //===--------------------------------------------------------------------===// @@ -8314,6 +8403,9 @@ public: return IsInOpenMPDeclareTargetContext; } + /// Return the number of captured regions created for an OpenMP directive. + static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind); + /// \brief Initialization of captured region for OpenMP region. void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope); /// \brief End of OpenMP region. @@ -9257,7 +9349,7 @@ public: ExprResult CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *CastExpr, CastKind &Kind); - ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, + ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, QualType Type, SourceLocation LParenLoc, Expr *CastExpr, SourceLocation RParenLoc); @@ -9265,14 +9357,14 @@ public: enum ARCConversionResult { ACR_okay, ACR_unbridged, ACR_error }; /// \brief Checks for invalid conversions and casts between - /// retainable pointers and other pointer kinds. - ARCConversionResult CheckObjCARCConversion(SourceRange castRange, - QualType castType, Expr *&op, - CheckedConversionKind CCK, - bool Diagnose = true, - bool DiagnoseCFAudited = false, - BinaryOperatorKind Opc = BO_PtrMemD - ); + /// retainable pointers and other pointer kinds for ARC and Weak. + ARCConversionResult CheckObjCConversion(SourceRange castRange, + QualType castType, Expr *&op, + CheckedConversionKind CCK, + bool Diagnose = true, + bool DiagnoseCFAudited = false, + BinaryOperatorKind Opc = BO_PtrMemD + ); Expr *stripARCUnbridgedCast(Expr *e); void diagnoseARCUnbridgedCast(Expr *e); @@ -9777,6 +9869,8 @@ public: void CodeCompletePostfixExpression(Scope *S, ExprResult LHS); void CodeCompleteTag(Scope *S, unsigned TagSpec); void CodeCompleteTypeQualifiers(DeclSpec &DS); + void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, + const VirtSpecifiers *VS = nullptr); void CodeCompleteBracketDeclarator(Scope *S); void CodeCompleteCase(Scope *S); void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args); @@ -9922,6 +10016,7 @@ private: bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall); + bool CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); @@ -10028,6 +10123,11 @@ private: void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field, Expr *Init); + /// Check if there is a field shadowing. + void CheckShadowInheritedFields(const SourceLocation &Loc, + DeclarationName FieldName, + const CXXRecordDecl *RD); + /// \brief Check if the given expression contains 'break' or 'continue' /// statement that produces control flow different from GCC. void CheckBreakContinueBinding(Expr *E); @@ -10221,6 +10321,7 @@ class EnterExpressionEvaluationContext { bool Entered = true; public: + EnterExpressionEvaluationContext(Sema &Actions, Sema::ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = nullptr, @@ -10251,8 +10352,8 @@ public: // a context. if (ShouldEnter && Actions.isUnevaluatedContext() && Actions.getLangOpts().CPlusPlus11) { - Actions.PushExpressionEvaluationContext(Sema::UnevaluatedList, nullptr, - false); + Actions.PushExpressionEvaluationContext( + Sema::ExpressionEvaluationContext::UnevaluatedList, nullptr, false); Entered = true; } } diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index 401bbbf1e566..644d55b93f1b 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -46,6 +46,10 @@ namespace clang { /// \brief The template argument lists, stored from the innermost template /// argument list (first) to the outermost template argument list (last). SmallVector<ArgList, 4> TemplateArgumentLists; + + /// \brief The number of outer levels of template arguments that are not + /// being substituted. + unsigned NumRetainedOuterLevels = 0; public: /// \brief Construct an empty set of template argument lists. @@ -59,11 +63,19 @@ namespace clang { /// \brief Determine the number of levels in this template argument /// list. - unsigned getNumLevels() const { return TemplateArgumentLists.size(); } - + unsigned getNumLevels() const { + return TemplateArgumentLists.size() + NumRetainedOuterLevels; + } + + /// \brief Determine the number of substituted levels in this template + /// argument list. + unsigned getNumSubstitutedLevels() const { + return TemplateArgumentLists.size(); + } + /// \brief Retrieve the template argument at a given depth and index. const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { - assert(Depth < TemplateArgumentLists.size()); + assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); return TemplateArgumentLists[getNumLevels() - Depth - 1][Index]; } @@ -73,7 +85,10 @@ namespace clang { /// /// There must exist a template argument list at the given depth. bool hasTemplateArgument(unsigned Depth, unsigned Index) const { - assert(Depth < TemplateArgumentLists.size()); + assert(Depth < getNumLevels()); + + if (Depth < NumRetainedOuterLevels) + return false; if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size()) return false; @@ -84,7 +99,7 @@ namespace clang { /// \brief Clear out a specific template argument. void setArgument(unsigned Depth, unsigned Index, TemplateArgument Arg) { - assert(Depth < TemplateArgumentLists.size()); + assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); const_cast<TemplateArgument&>( TemplateArgumentLists[getNumLevels() - Depth - 1][Index]) @@ -101,9 +116,18 @@ namespace clang { /// \brief Add a new outmost level to the multi-level template argument /// list. void addOuterTemplateArguments(ArgList Args) { + assert(!NumRetainedOuterLevels && + "substituted args outside retained args?"); TemplateArgumentLists.push_back(Args); } + /// \brief Add an outermost level that we are not substituting. We have no + /// arguments at this level, and do not remove it from the depth of inner + /// template parameters that we instantiate. + void addOuterRetainedLevel() { + ++NumRetainedOuterLevels; + } + /// \brief Retrieve the innermost template argument list. const ArgList &getInnermost() const { return TemplateArgumentLists.front(); |
