summaryrefslogtreecommitdiff
path: root/include/clang/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Sema')
-rw-r--r--include/clang/Sema/AttributeList.h1
-rw-r--r--include/clang/Sema/DeclSpec.h63
-rw-r--r--include/clang/Sema/IdentifierResolver.h16
-rw-r--r--include/clang/Sema/Initialization.h40
-rw-r--r--include/clang/Sema/Lookup.h2
-rw-r--r--include/clang/Sema/MultiplexExternalSemaSource.h2
-rw-r--r--include/clang/Sema/Overload.h1
-rw-r--r--include/clang/Sema/Ownership.h1
-rw-r--r--include/clang/Sema/ScopeInfo.h81
-rw-r--r--include/clang/Sema/Sema.h369
-rw-r--r--include/clang/Sema/Template.h34
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();