summaryrefslogtreecommitdiff
path: root/clang/include/clang/Sema/Sema.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/Sema/Sema.h')
-rw-r--r--clang/include/clang/Sema/Sema.h1053
1 files changed, 850 insertions, 203 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 47a055f696b13..6f7ad8076718d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_SEMA_SEMA_H
#include "clang/AST/ASTConcept.h"
+#include "clang/AST/ASTFwd.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Availability.h"
#include "clang/AST/ComparisonCategories.h"
@@ -22,7 +23,9 @@
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/LocInfoType.h"
#include "clang/AST/MangleNumberingContext.h"
@@ -34,6 +37,7 @@
#include "clang/Basic/BitmaskEnum.h"
#include "clang/Basic/ExpressionTraits.h"
#include "clang/Basic/Module.h"
+#include "clang/Basic/OpenCLOptions.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/PragmaKinds.h"
#include "clang/Basic/Specifiers.h"
@@ -54,6 +58,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/TinyPtrVector.h"
@@ -372,12 +377,22 @@ class Sema final {
ArrayRef<QualType> Args);
public:
+ /// The maximum alignment, same as in llvm::Value. We duplicate them here
+ /// because that allows us not to duplicate the constants in clang code,
+ /// which we must to since we can't directly use the llvm constants.
+ /// The value is verified against llvm here: lib/CodeGen/CGDecl.cpp
+ ///
+ /// This is the greatest alignment value supported by load, store, and alloca
+ /// instructions, and global values.
+ static const unsigned MaxAlignmentExponent = 29;
+ static const unsigned MaximumAlignment = 1u << MaxAlignmentExponent;
+
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
typedef OpaquePtr<TemplateName> TemplateTy;
typedef OpaquePtr<QualType> TypeTy;
OpenCLOptions OpenCLFeatures;
- FPOptions FPFeatures;
+ FPOptions CurFPFeatures;
const LangOptions &LangOpts;
Preprocessor &PP;
@@ -475,10 +490,41 @@ public:
PragmaLocation(PragmaLocation),
PragmaPushLocation(PragmaPushLocation) {}
};
- void Act(SourceLocation PragmaLocation,
- PragmaMsStackAction Action,
- llvm::StringRef StackSlotLabel,
- ValueType Value);
+
+ void Act(SourceLocation PragmaLocation, PragmaMsStackAction Action,
+ llvm::StringRef StackSlotLabel, ValueType Value) {
+ if (Action == PSK_Reset) {
+ CurrentValue = DefaultValue;
+ CurrentPragmaLocation = PragmaLocation;
+ return;
+ }
+ if (Action & PSK_Push)
+ Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation,
+ PragmaLocation);
+ else if (Action & PSK_Pop) {
+ if (!StackSlotLabel.empty()) {
+ // If we've got a label, try to find it and jump there.
+ auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
+ return x.StackSlotLabel == StackSlotLabel;
+ });
+ // If we found the label so pop from there.
+ if (I != Stack.rend()) {
+ CurrentValue = I->Value;
+ CurrentPragmaLocation = I->PragmaLocation;
+ Stack.erase(std::prev(I.base()), Stack.end());
+ }
+ } else if (!Stack.empty()) {
+ // We do not have a label, just pop the last entry.
+ CurrentValue = Stack.back().Value;
+ CurrentPragmaLocation = Stack.back().PragmaLocation;
+ Stack.pop_back();
+ }
+ }
+ if (Action & PSK_Set) {
+ CurrentValue = Value;
+ CurrentPragmaLocation = PragmaLocation;
+ }
+ }
// MSVC seems to add artificial slots to #pragma stacks on entering a C++
// method body to restore the stacks on exit, so it works like this:
@@ -540,6 +586,18 @@ public:
PragmaStack<StringLiteral *> ConstSegStack;
PragmaStack<StringLiteral *> CodeSegStack;
+ // This stack tracks the current state of Sema.CurFPFeatures.
+ PragmaStack<unsigned> FpPragmaStack;
+ FPOptionsOverride CurFPFeatureOverrides() {
+ FPOptionsOverride result;
+ if (!FpPragmaStack.hasValue()) {
+ result = FPOptionsOverride();
+ } else {
+ result = FPOptionsOverride(FpPragmaStack.CurrentValue);
+ }
+ return result;
+ }
+
// RAII object to push / pop sentinel slots for all MS #pragma stacks.
// Actions should be performed only if we enter / exit a C++ method body.
class PragmaStackSentinelRAII {
@@ -601,16 +659,16 @@ public:
CleanupInfo Cleanup;
/// ExprCleanupObjects - This is the stack of objects requiring
- /// cleanup that are created by the current full expression. The
- /// element type here is ExprWithCleanups::Object.
- SmallVector<BlockDecl*, 8> ExprCleanupObjects;
+ /// cleanup that are created by the current full expression.
+ SmallVector<ExprWithCleanups::CleanupObject, 8> ExprCleanupObjects;
/// Store a set of either DeclRefExprs or MemberExprs that contain a reference
/// to a variable (constant) that may or may not be odr-used in this Expr, and
/// we won't know until all lvalue-to-rvalue and discarded value conversions
/// have been applied to all subexpressions of the enclosing full expression.
/// This is cleared at the end of each full expression.
- using MaybeODRUseExprSet = llvm::SmallPtrSet<Expr *, 2>;
+ using MaybeODRUseExprSet = llvm::SetVector<Expr *, SmallVector<Expr *, 4>,
+ llvm::SmallPtrSet<Expr *, 4>>;
MaybeODRUseExprSet MaybeODRUseExprs;
std::unique_ptr<sema::FunctionScopeInfo> CachedFunctionScope;
@@ -619,6 +677,32 @@ public:
/// function, block, and method scopes that are currently active.
SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes;
+ /// The index of the first FunctionScope that corresponds to the current
+ /// context.
+ unsigned FunctionScopesStart = 0;
+
+ ArrayRef<sema::FunctionScopeInfo*> getFunctionScopes() const {
+ return llvm::makeArrayRef(FunctionScopes.begin() + FunctionScopesStart,
+ FunctionScopes.end());
+ }
+
+ /// Stack containing information needed when in C++2a an 'auto' is encountered
+ /// in a function declaration parameter type specifier in order to invent a
+ /// corresponding template parameter in the enclosing abbreviated function
+ /// template. This information is also present in LambdaScopeInfo, stored in
+ /// the FunctionScopes stack.
+ SmallVector<InventedTemplateParameterInfo, 4> InventedParameterInfos;
+
+ /// The index of the first InventedParameterInfo that refers to the current
+ /// context.
+ unsigned InventedParameterInfosStart = 0;
+
+ ArrayRef<InventedTemplateParameterInfo> getInventedParameterInfos() const {
+ return llvm::makeArrayRef(InventedParameterInfos.begin() +
+ InventedParameterInfosStart,
+ InventedParameterInfos.end());
+ }
+
typedef LazyVector<TypedefNameDecl *, ExternalSemaSource,
&ExternalSemaSource::ReadExtVectorDecls, 2, 2>
ExtVectorDeclsType;
@@ -792,17 +876,24 @@ public:
DeclContext *SavedContext;
ProcessingContextState SavedContextState;
QualType SavedCXXThisTypeOverride;
+ unsigned SavedFunctionScopesStart;
+ unsigned SavedInventedParameterInfosStart;
public:
ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true)
: S(S), SavedContext(S.CurContext),
SavedContextState(S.DelayedDiagnostics.pushUndelayed()),
- SavedCXXThisTypeOverride(S.CXXThisTypeOverride)
+ SavedCXXThisTypeOverride(S.CXXThisTypeOverride),
+ SavedFunctionScopesStart(S.FunctionScopesStart),
+ SavedInventedParameterInfosStart(S.InventedParameterInfosStart)
{
assert(ContextToPush && "pushing null context");
S.CurContext = ContextToPush;
if (NewThisContext)
S.CXXThisTypeOverride = QualType();
+ // Any saved FunctionScopes do not refer to this context.
+ S.FunctionScopesStart = S.FunctionScopes.size();
+ S.InventedParameterInfosStart = S.InventedParameterInfos.size();
}
void pop() {
@@ -810,6 +901,8 @@ public:
S.CurContext = SavedContext;
S.DelayedDiagnostics.popUndelayed(SavedContextState);
S.CXXThisTypeOverride = SavedCXXThisTypeOverride;
+ S.FunctionScopesStart = SavedFunctionScopesStart;
+ S.InventedParameterInfosStart = SavedInventedParameterInfosStart;
SavedContext = nullptr;
}
@@ -818,6 +911,11 @@ public:
}
};
+ /// Whether the AST is currently being rebuilt to correct immediate
+ /// invocations. Immediate invocation candidates and references to consteval
+ /// functions aren't tracked when this is set.
+ bool RebuildingImmediateInvocation = false;
+
/// Used to change context to isConstantEvaluated without pushing a heavy
/// ExpressionEvaluationContextRecord object.
bool isConstantEvaluatedOverride;
@@ -1029,6 +1127,8 @@ public:
PotentiallyEvaluatedIfUsed
};
+ using ImmediateInvocationCandidate = llvm::PointerIntPair<ConstantExpr *, 1>;
+
/// Data structure used to record current or nested
/// expression evaluation contexts.
struct ExpressionEvaluationContextRecord {
@@ -1075,6 +1175,13 @@ public:
/// they are not discarded-value expressions nor unevaluated operands.
SmallVector<Expr*, 2> VolatileAssignmentLHSs;
+ /// Set of candidates for starting an immediate invocation.
+ llvm::SmallVector<ImmediateInvocationCandidate, 4> ImmediateInvocationCandidates;
+
+ /// Set of DeclRefExprs referencing a consteval function when used in a
+ /// context not already known to be immediately invoked.
+ llvm::SmallPtrSet<DeclRefExpr *, 4> ReferenceToConsteval;
+
/// \brief Describes whether we are in an expression constext which we have
/// to handle differently.
enum ExpressionKind {
@@ -1287,16 +1394,23 @@ public:
/// should not be used elsewhere.
void EmitCurrentDiagnostic(unsigned DiagID);
- /// Records and restores the FP_CONTRACT state on entry/exit of compound
+ /// Records and restores the CurFPFeatures state on entry/exit of compound
/// statements.
- class FPContractStateRAII {
+ class FPFeaturesStateRAII {
public:
- FPContractStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.FPFeatures) {}
- ~FPContractStateRAII() { S.FPFeatures = OldFPFeaturesState; }
+ FPFeaturesStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.CurFPFeatures) {
+ OldOverrides = S.FpPragmaStack.CurrentValue;
+ }
+ ~FPFeaturesStateRAII() {
+ S.CurFPFeatures = OldFPFeaturesState;
+ S.FpPragmaStack.CurrentValue = OldOverrides;
+ }
+ unsigned getOverrides() { return OldOverrides; }
private:
Sema& S;
FPOptions OldFPFeaturesState;
+ unsigned OldOverrides;
};
void addImplicitTypedef(StringRef Name, QualType T);
@@ -1315,7 +1429,7 @@ public:
const LangOptions &getLangOpts() const { return LangOpts; }
OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; }
- FPOptions &getFPOptions() { return FPFeatures; }
+ FPOptions &getCurFPFeatures() { return CurFPFeatures; }
DiagnosticsEngine &getDiagnostics() const { return Diags; }
SourceManager &getSourceManager() const { return SourceMgr; }
@@ -1424,8 +1538,22 @@ public:
/// Retrieve the module loader associated with the preprocessor.
ModuleLoader &getModuleLoader() const;
+ /// Invent a new identifier for parameters of abbreviated templates.
+ IdentifierInfo *
+ InventAbbreviatedTemplateParameterTypeName(IdentifierInfo *ParamName,
+ unsigned Index);
+
void emitAndClearUnusedLocalTypedefWarnings();
+ private:
+ /// Function or variable declarations to be checked for whether the deferred
+ /// diagnostics should be emitted.
+ SmallVector<Decl *, 4> DeclsToCheckForDeferredDiags;
+
+ public:
+ // Emit all deferred diagnostics.
+ void emitDeferredDiags();
+
enum TUFragmentKind {
/// The global module fragment, between 'module;' and a module-declaration.
Global,
@@ -1518,6 +1646,15 @@ public:
/// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls
SmallVectorImpl<Decl *> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
+ /// Called before parsing a function declarator belonging to a function
+ /// declaration.
+ void ActOnStartFunctionDeclarationDeclarator(Declarator &D,
+ unsigned TemplateParameterDepth);
+
+ /// Called after parsing a function declarator belonging to a function
+ /// declaration.
+ void ActOnFinishFunctionDeclarationDeclarator(Declarator &D);
+
void ActOnComment(SourceRange Comment);
//===--------------------------------------------------------------------===//
@@ -1538,6 +1675,9 @@ public:
QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc);
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc);
+ QualType BuildMatrixType(QualType T, Expr *NumRows, Expr *NumColumns,
+ SourceLocation AttrLoc);
+
QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace,
SourceLocation AttrLoc);
@@ -1592,6 +1732,7 @@ public:
SourceLocation Loc);
QualType BuildWritePipeType(QualType T,
SourceLocation Loc);
+ QualType BuildExtIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc);
TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
@@ -1603,6 +1744,10 @@ public:
static QualType GetTypeFromParser(ParsedType Ty,
TypeSourceInfo **TInfo = nullptr);
CanThrowResult canThrow(const Stmt *E);
+ /// Determine whether the callee of a particular function call can throw.
+ /// E, D and Loc are all optional.
+ static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D,
+ SourceLocation Loc = SourceLocation());
const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc,
const FunctionProtoType *FPT);
void UpdateExceptionSpec(FunctionDecl *FD,
@@ -1664,6 +1809,7 @@ public:
static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();}
template <typename... Ts> class BoundTypeDiagnoser : public TypeDiagnoser {
+ protected:
unsigned DiagID;
std::tuple<const Ts &...> Args;
@@ -1688,6 +1834,37 @@ public:
}
};
+ /// A derivative of BoundTypeDiagnoser for which the diagnostic's type
+ /// parameter is preceded by a 0/1 enum that is 1 if the type is sizeless.
+ /// For example, a diagnostic with no other parameters would generally have
+ /// the form "...%select{incomplete|sizeless}0 type %1...".
+ template <typename... Ts>
+ class SizelessTypeDiagnoser : public BoundTypeDiagnoser<Ts...> {
+ public:
+ SizelessTypeDiagnoser(unsigned DiagID, const Ts &... Args)
+ : BoundTypeDiagnoser<Ts...>(DiagID, Args...) {}
+
+ void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
+ const SemaDiagnosticBuilder &DB = S.Diag(Loc, this->DiagID);
+ this->emit(DB, std::index_sequence_for<Ts...>());
+ DB << T->isSizelessType() << T;
+ }
+ };
+
+ enum class CompleteTypeKind {
+ /// Apply the normal rules for complete types. In particular,
+ /// treat all sizeless types as incomplete.
+ Normal,
+
+ /// Relax the normal rules for complete types so that they include
+ /// sizeless built-in types.
+ AcceptSizeless,
+
+ // FIXME: Eventually we should flip the default to Normal and opt in
+ // to AcceptSizeless rather than opt out of it.
+ Default = AcceptSizeless
+ };
+
private:
/// Methods for marking which expressions involve dereferencing a pointer
/// marked with the 'noderef' attribute. Expressions are checked bottom up as
@@ -1701,7 +1878,7 @@ private:
void CheckMemberAccessOfNoDeref(const MemberExpr *E);
bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
- TypeDiagnoser *Diagnoser);
+ CompleteTypeKind Kind, TypeDiagnoser *Diagnoser);
struct ModuleScope {
SourceLocation BeginLoc;
@@ -1737,7 +1914,7 @@ public:
/// Determine whether a declaration is visible to name lookup.
bool isVisible(const NamedDecl *D) {
- return !D->isHidden() || isVisibleSlow(D);
+ return D->isUnconditionallyVisible() || isVisibleSlow(D);
}
/// Determine whether any declaration of an entity is visible.
@@ -1792,13 +1969,22 @@ public:
bool isUsualDeallocationFunction(const CXXMethodDecl *FD);
- bool isCompleteType(SourceLocation Loc, QualType T) {
- return !RequireCompleteTypeImpl(Loc, T, nullptr);
+ bool isCompleteType(SourceLocation Loc, QualType T,
+ CompleteTypeKind Kind = CompleteTypeKind::Default) {
+ return !RequireCompleteTypeImpl(Loc, T, Kind, nullptr);
}
bool RequireCompleteType(SourceLocation Loc, QualType T,
- TypeDiagnoser &Diagnoser);
+ CompleteTypeKind Kind, TypeDiagnoser &Diagnoser);
bool RequireCompleteType(SourceLocation Loc, QualType T,
- unsigned DiagID);
+ CompleteTypeKind Kind, unsigned DiagID);
+
+ bool RequireCompleteType(SourceLocation Loc, QualType T,
+ TypeDiagnoser &Diagnoser) {
+ return RequireCompleteType(Loc, T, CompleteTypeKind::Default, Diagnoser);
+ }
+ bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID) {
+ return RequireCompleteType(Loc, T, CompleteTypeKind::Default, DiagID);
+ }
template <typename... Ts>
bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID,
@@ -1807,14 +1993,29 @@ public:
return RequireCompleteType(Loc, T, Diagnoser);
}
+ template <typename... Ts>
+ bool RequireCompleteSizedType(SourceLocation Loc, QualType T, unsigned DiagID,
+ const Ts &... Args) {
+ SizelessTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
+ return RequireCompleteType(Loc, T, CompleteTypeKind::Normal, Diagnoser);
+ }
+
void completeExprArrayBound(Expr *E);
- bool RequireCompleteExprType(Expr *E, TypeDiagnoser &Diagnoser);
+ bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind,
+ TypeDiagnoser &Diagnoser);
bool RequireCompleteExprType(Expr *E, unsigned DiagID);
template <typename... Ts>
bool RequireCompleteExprType(Expr *E, unsigned DiagID, const Ts &...Args) {
BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
- return RequireCompleteExprType(E, Diagnoser);
+ return RequireCompleteExprType(E, CompleteTypeKind::Default, Diagnoser);
+ }
+
+ template <typename... Ts>
+ bool RequireCompleteSizedExprType(Expr *E, unsigned DiagID,
+ const Ts &... Args) {
+ SizelessTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
+ return RequireCompleteExprType(E, CompleteTypeKind::Normal, Diagnoser);
}
bool RequireLiteralType(SourceLocation Loc, QualType T,
@@ -1921,6 +2122,8 @@ public:
NC_FunctionTemplate,
/// The name was classified as an ADL-only function template name.
NC_UndeclaredTemplate,
+ /// The name was classified as a concept name.
+ NC_Concept,
};
class NameClassification {
@@ -1985,6 +2188,12 @@ public:
return Result;
}
+ static NameClassification Concept(TemplateName Name) {
+ NameClassification Result(NC_Concept);
+ Result.Template = Name;
+ return Result;
+ }
+
static NameClassification UndeclaredTemplate(TemplateName Name) {
NameClassification Result(NC_UndeclaredTemplate);
Result.Template = Name;
@@ -2010,7 +2219,8 @@ public:
TemplateName getTemplateName() const {
assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate ||
- Kind == NC_VarTemplate || Kind == NC_UndeclaredTemplate);
+ Kind == NC_VarTemplate || Kind == NC_Concept ||
+ Kind == NC_UndeclaredTemplate);
return Template;
}
@@ -2022,6 +2232,8 @@ public:
return TNK_Function_template;
case NC_VarTemplate:
return TNK_Var_template;
+ case NC_Concept:
+ return TNK_Concept_template;
case NC_UndeclaredTemplate:
return TNK_Undeclared_template;
default:
@@ -2221,11 +2433,13 @@ public:
void ActOnParamDefaultArgument(Decl *param,
SourceLocation EqualLoc,
Expr *defarg);
- void ActOnParamUnparsedDefaultArgument(Decl *param,
- SourceLocation EqualLoc,
+ void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc,
SourceLocation ArgLoc);
void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc);
- bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
+ ExprResult ConvertParamDefaultArgument(const ParmVarDecl *Param,
+ Expr *DefaultArg,
+ SourceLocation EqualLoc);
+ void SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
SourceLocation EqualLoc);
// Contexts where using non-trivial C union types can be disallowed. This is
@@ -2699,8 +2913,6 @@ public:
Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S,
const ParsedAttributesView &Attr);
- DeclContext *getContainingDC(DeclContext *DC);
-
/// Set the current declaration context until it gets popped.
void PushDeclContext(Scope *S, DeclContext *DC);
void PopDeclContext();
@@ -2710,6 +2922,11 @@ public:
void EnterDeclaratorContext(Scope *S, DeclContext *DC);
void ExitDeclaratorContext(Scope *S);
+ /// Enter a template parameter scope, after it's been associated with a particular
+ /// DeclContext. Causes lookup within the scope to chain through enclosing contexts
+ /// in the correct order.
+ void EnterTemplatedContext(Scope *S, DeclContext *DC);
+
/// Push the parameters of D, which must be a function, into scope.
void ActOnReenterFunctionContext(Scope* S, Decl* D);
void ActOnExitFunctionContext();
@@ -2808,7 +3025,7 @@ public:
VisibilityAttr *mergeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI,
VisibilityAttr::VisibilityType Vis);
UuidAttr *mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI,
- StringRef Uuid);
+ StringRef UuidAsWritten, MSGuidDecl *GuidDecl);
DLLImportAttr *mergeDLLImportAttr(Decl *D, const AttributeCommonInfo &CI);
DLLExportAttr *mergeDLLExportAttr(Decl *D, const AttributeCommonInfo &CI);
MSInheritanceAttr *mergeMSInheritanceAttr(Decl *D,
@@ -2839,6 +3056,10 @@ public:
const InternalLinkageAttr &AL);
CommonAttr *mergeCommonAttr(Decl *D, const ParsedAttr &AL);
CommonAttr *mergeCommonAttr(Decl *D, const CommonAttr &AL);
+ WebAssemblyImportNameAttr *mergeImportNameAttr(
+ Decl *D, const WebAssemblyImportNameAttr &AL);
+ WebAssemblyImportModuleAttr *mergeImportModuleAttr(
+ Decl *D, const WebAssemblyImportModuleAttr &AL);
void mergeDeclAttributes(NamedDecl *New, Decl *Old,
AvailabilityMergeKind AMK = AMK_Redeclaration);
@@ -2892,10 +3113,19 @@ public:
bool ConsiderCudaAttrs = true,
bool ConsiderRequiresClauses = true);
+ enum class AllowedExplicit {
+ /// Allow no explicit functions to be used.
+ None,
+ /// Allow explicit conversion functions but not explicit constructors.
+ Conversions,
+ /// Allow both explicit conversion functions and explicit constructors.
+ All
+ };
+
ImplicitConversionSequence
TryImplicitConversion(Expr *From, QualType ToType,
bool SuppressUserConversions,
- bool AllowExplicit,
+ AllowedExplicit AllowExplicit,
bool InOverloadResolution,
bool CStyle,
bool AllowObjCWritebackConversion);
@@ -3202,7 +3432,8 @@ public:
/// Check the enable_if expressions on the given function. Returns the first
/// failing attribute, or NULL if they were all successful.
- EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
+ EnableIfAttr *CheckEnableIf(FunctionDecl *Function, SourceLocation CallLoc,
+ ArrayRef<Expr *> Args,
bool MissingImplicitThis = false);
/// Find the failed Boolean condition within a given Boolean
@@ -3412,6 +3643,9 @@ public:
/// operator overloading. This lookup is similar to ordinary name
/// lookup, but will ignore any declarations that are class members.
LookupOperatorName,
+ /// Look up a name following ~ in a destructor name. This is an ordinary
+ /// lookup, but prefers tags to typedefs.
+ LookupDestructorName,
/// Look up of a name that precedes the '::' scope resolution
/// operator in C++. This lookup completely ignores operator, object,
/// function, and enumerator names (C++ [basic.lookup.qual]p1).
@@ -3522,7 +3756,7 @@ private:
/// Creates a new TypoExpr AST node.
TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
TypoDiagnosticGenerator TDG,
- TypoRecoveryCallback TRC);
+ TypoRecoveryCallback TRC, SourceLocation TypoLoc);
// The set of known/encountered (unique, canonicalized) NamespaceDecls.
//
@@ -3613,7 +3847,8 @@ public:
TemplateDiscarded, // Discarded due to uninstantiated templates
Unknown,
};
- FunctionEmissionStatus getEmissionStatus(FunctionDecl *Decl);
+ FunctionEmissionStatus getEmissionStatus(FunctionDecl *Decl,
+ bool Final = false);
// Whether the callee should be ignored in CUDA/HIP/OpenMP host/device check.
bool shouldIgnoreInHostDeviceCheck(FunctionDecl *Callee);
@@ -3666,32 +3901,28 @@ public:
/// \param InitDecl A VarDecl to avoid because the Expr being corrected is its
/// initializer.
///
+ /// \param RecoverUncorrectedTypos If true, when typo correction fails, it
+ /// will rebuild the given Expr with all TypoExprs degraded to RecoveryExprs.
+ ///
/// \param Filter A function applied to a newly rebuilt Expr to determine if
/// it is an acceptable/usable result from a single combination of typo
/// corrections. As long as the filter returns ExprError, different
/// combinations of corrections will be tried until all are exhausted.
- ExprResult
- CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl = nullptr,
- llvm::function_ref<ExprResult(Expr *)> Filter =
- [](Expr *E) -> ExprResult { return E; });
-
- ExprResult
- CorrectDelayedTyposInExpr(Expr *E,
- llvm::function_ref<ExprResult(Expr *)> Filter) {
- return CorrectDelayedTyposInExpr(E, nullptr, Filter);
- }
-
- ExprResult
- CorrectDelayedTyposInExpr(ExprResult ER, VarDecl *InitDecl = nullptr,
- llvm::function_ref<ExprResult(Expr *)> Filter =
- [](Expr *E) -> ExprResult { return E; }) {
- return ER.isInvalid() ? ER : CorrectDelayedTyposInExpr(ER.get(), Filter);
- }
-
- ExprResult
- CorrectDelayedTyposInExpr(ExprResult ER,
- llvm::function_ref<ExprResult(Expr *)> Filter) {
- return CorrectDelayedTyposInExpr(ER, nullptr, Filter);
+ ExprResult CorrectDelayedTyposInExpr(
+ Expr *E, VarDecl *InitDecl = nullptr,
+ bool RecoverUncorrectedTypos = false,
+ llvm::function_ref<ExprResult(Expr *)> Filter =
+ [](Expr *E) -> ExprResult { return E; });
+
+ ExprResult CorrectDelayedTyposInExpr(
+ ExprResult ER, VarDecl *InitDecl = nullptr,
+ bool RecoverUncorrectedTypos = false,
+ llvm::function_ref<ExprResult(Expr *)> Filter =
+ [](Expr *E) -> ExprResult { return E; }) {
+ return ER.isInvalid()
+ ? ER
+ : CorrectDelayedTyposInExpr(ER.get(), InitDecl,
+ RecoverUncorrectedTypos, Filter);
}
void diagnoseTypo(const TypoCorrection &Correction,
@@ -3718,6 +3949,11 @@ public:
void DiagnoseAmbiguousLookup(LookupResult &Result);
//@}
+ /// Attempts to produce a RecoveryExpr after some AST node cannot be created.
+ ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End,
+ ArrayRef<Expr *> SubExprs,
+ QualType T = QualType());
+
ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id,
SourceLocation IdLoc,
bool TypoCorrection = false);
@@ -3726,6 +3962,8 @@ public:
SourceLocation Loc);
NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
Scope *S);
+ void AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction(
+ FunctionDecl *FD);
void AddKnownFunctionAttributes(FunctionDecl *FD);
// More parsing and symbol table subroutines.
@@ -4139,7 +4377,8 @@ public:
ConditionResult Cond);
StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
Stmt *Switch, Stmt *Body);
- StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,
+ StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
+ ConditionResult Cond, SourceLocation RParenLoc,
Stmt *Body);
StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
SourceLocation WhileLoc, SourceLocation CondLParen,
@@ -4380,6 +4619,8 @@ public:
/// Issue any -Wunguarded-availability warnings in \c FD
void DiagnoseUnguardedAvailabilityViolations(Decl *FD);
+ void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
+
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks: SemaExpr.cpp.
@@ -4516,6 +4757,10 @@ public:
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy,
UnresolvedSetImpl &NonTemplateOverloads);
+ /// Try to convert an expression \p E to type \p Ty. Returns the result of the
+ /// conversion.
+ ExprResult tryConvertExprToType(Expr *E, QualType Ty);
+
/// Conditionally issue a diagnostic based on the current
/// evaluation context.
///
@@ -4642,6 +4887,15 @@ public:
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
+ ExprResult BuildUniqueStableName(SourceLocation Loc, TypeSourceInfo *Operand);
+ ExprResult BuildUniqueStableName(SourceLocation Loc, Expr *E);
+ ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc,
+ SourceLocation LParen,
+ SourceLocation RParen, ParsedType Ty);
+ ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc,
+ SourceLocation LParen,
+ SourceLocation RParen, Expr *E);
+
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc);
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
@@ -4712,9 +4966,36 @@ public:
Expr *Idx, SourceLocation RLoc);
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
Expr *Idx, SourceLocation RLoc);
+
+ ExprResult CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
+ Expr *ColumnIdx,
+ SourceLocation RBLoc);
+
ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
- Expr *LowerBound, SourceLocation ColonLoc,
- Expr *Length, SourceLocation RBLoc);
+ Expr *LowerBound,
+ SourceLocation ColonLocFirst,
+ SourceLocation ColonLocSecond,
+ Expr *Length, Expr *Stride,
+ SourceLocation RBLoc);
+ ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
+ SourceLocation RParenLoc,
+ ArrayRef<Expr *> Dims,
+ ArrayRef<SourceRange> Brackets);
+
+ /// Data structure for iterator expression.
+ struct OMPIteratorData {
+ IdentifierInfo *DeclIdent = nullptr;
+ SourceLocation DeclIdentLoc;
+ ParsedType Type;
+ OMPIteratorExpr::IteratorRange Range;
+ SourceLocation AssignLoc;
+ SourceLocation ColonLoc;
+ SourceLocation SecColonLoc;
+ };
+
+ ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc,
+ SourceLocation LLoc, SourceLocation RLoc,
+ ArrayRef<OMPIteratorData> Data);
// This struct is for use by ActOnMemberAccess to allow
// BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after
@@ -4890,8 +5171,10 @@ public:
LabelDecl *TheDecl);
void ActOnStartStmtExpr();
- ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
- SourceLocation RPLoc); // "({..})"
+ ExprResult ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt,
+ SourceLocation RPLoc);
+ ExprResult BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
+ SourceLocation RPLoc, unsigned TemplateDepth);
// Handle the final expression in a statement expression.
ExprResult ActOnStmtExprResult(ExprResult E);
void ActOnStmtExprError();
@@ -5467,6 +5750,10 @@ public:
/// it simply returns the passed in expression.
ExprResult MaybeBindToTemporary(Expr *E);
+ /// Wrap the expression in a ConstantExpr if it is a potential immediate
+ /// invocation.
+ ExprResult CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl);
+
bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
MultiExprArg ArgsPtr,
SourceLocation Loc,
@@ -5494,7 +5781,8 @@ public:
void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
bool IsDereference, SourceRange Range);
- /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
+ /// ActOnCXXNamedCast - Parse
+ /// {dynamic,static,reinterpret,const,addrspace}_cast's.
ExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
tok::TokenKind Kind,
SourceLocation LAngleBracketLoc,
@@ -6178,15 +6466,10 @@ public:
/// A diagnostic is emitted if it is not, false is returned, and
/// PossibleNonPrimary will be set to true if the failure might be due to a
/// non-primary expression being used as an atomic constraint.
- bool CheckConstraintExpression(Expr *CE, Token NextToken = Token(),
+ bool CheckConstraintExpression(const Expr *CE, Token NextToken = Token(),
bool *PossibleNonPrimary = nullptr,
bool IsTrailingRequiresClause = false);
- /// Check whether the given type-dependent expression will be the name of a
- /// function or another callable function-like entity (e.g. a function
- // template or overload set) for any substitution.
- bool IsDependentFunctionNameExpr(Expr *E);
-
private:
/// Caches pairs of template-like decls whose associated constraints were
/// checked for subsumption and whether or not the first's constraints did in
@@ -6199,6 +6482,9 @@ private:
llvm::DenseMap<NamedDecl *, NormalizedConstraint *>
NormalizationCache;
+ llvm::ContextualFoldingSet<ConstraintSatisfaction, const ASTContext &>
+ SatisfactionCache;
+
public:
const NormalizedConstraint *
getNormalizedAssociatedConstraints(
@@ -6225,6 +6511,8 @@ public:
/// \brief Check whether the given list of constraint expressions are
/// satisfied (as if in a 'conjunction') given template arguments.
+ /// \param Template the template-like entity that triggered the constraints
+ /// check (either a concept or a constrained entity).
/// \param ConstraintExprs a list of constraint expressions, treated as if
/// they were 'AND'ed together.
/// \param TemplateArgs the list of template arguments to substitute into the
@@ -6236,23 +6524,10 @@ public:
/// expression.
/// \returns true if an error occurred and satisfaction could not be checked,
/// false otherwise.
- bool CheckConstraintSatisfaction(TemplateDecl *Template,
- ArrayRef<const Expr *> ConstraintExprs,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange TemplateIDRange,
- ConstraintSatisfaction &Satisfaction);
-
- bool CheckConstraintSatisfaction(ClassTemplatePartialSpecializationDecl *TD,
- ArrayRef<const Expr *> ConstraintExprs,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange TemplateIDRange,
- ConstraintSatisfaction &Satisfaction);
-
- bool CheckConstraintSatisfaction(VarTemplatePartialSpecializationDecl *TD,
- ArrayRef<const Expr *> ConstraintExprs,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange TemplateIDRange,
- ConstraintSatisfaction &Satisfaction);
+ bool CheckConstraintSatisfaction(
+ const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+ ArrayRef<TemplateArgument> TemplateArgs,
+ SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction);
/// \brief Check whether the given non-dependent constraint expression is
/// satisfied. Returns false and updates Satisfaction with the satisfaction
@@ -6263,6 +6538,17 @@ public:
bool CheckConstraintSatisfaction(const Expr *ConstraintExpr,
ConstraintSatisfaction &Satisfaction);
+ /// Check whether the given function decl's trailing requires clause is
+ /// satisfied, if any. Returns false and updates Satisfaction with the
+ /// satisfaction verdict if successful, emits a diagnostic and returns true if
+ /// an error occured and satisfaction could not be determined.
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ bool CheckFunctionConstraints(const FunctionDecl *FD,
+ ConstraintSatisfaction &Satisfaction,
+ SourceLocation UsageLoc = SourceLocation());
+
+
/// \brief Ensure that the given template arguments satisfy the constraints
/// associated with the given template, emitting a diagnostic if they do not.
///
@@ -6282,13 +6568,17 @@ public:
/// \brief Emit diagnostics explaining why a constraint expression was deemed
/// unsatisfied.
+ /// \param First whether this is the first time an unsatisfied constraint is
+ /// diagnosed for this error.
void
- DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction);
+ DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction,
+ bool First = true);
/// \brief Emit diagnostics explaining why a constraint expression was deemed
/// unsatisfied.
void
- DiagnoseUnsatisfiedConstraint(const ASTConstraintSatisfaction& Satisfaction);
+ DiagnoseUnsatisfiedConstraint(const ASTConstraintSatisfaction &Satisfaction,
+ bool First = true);
/// \brief Emit diagnostics explaining why a constraint expression was deemed
/// unsatisfied because it was ill-formed.
@@ -6452,6 +6742,22 @@ public:
void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
CXXRecordDecl *Record);
+ /// Mark destructors of virtual bases of this class referenced. In the Itanium
+ /// C++ ABI, this is done when emitting a destructor for any non-abstract
+ /// class. In the Microsoft C++ ABI, this is done any time a class's
+ /// destructor is referenced.
+ void MarkVirtualBaseDestructorsReferenced(
+ SourceLocation Location, CXXRecordDecl *ClassDecl,
+ llvm::SmallPtrSetImpl<const RecordType *> *DirectVirtualBases = nullptr);
+
+ /// Do semantic checks to allow the complete destructor variant to be emitted
+ /// when the destructor is defined in another translation unit. In the Itanium
+ /// C++ ABI, destructor variants are emitted together. In the MS C++ ABI, they
+ /// can be emitted in separate TUs. To emit the complete variant, run a subset
+ /// of the checks performed when emitting a regular destructor.
+ void CheckCompleteDestructorVariant(SourceLocation CurrentLocation,
+ CXXDestructorDecl *Dtor);
+
/// The list of classes whose vtables have been used within
/// this translation unit, and the source locations at which the
/// first use occurred.
@@ -6537,7 +6843,8 @@ public:
void ActOnFinishCXXNonNestedClass();
void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param);
- unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template);
+ unsigned ActOnReenterTemplateScope(Decl *Template,
+ llvm::function_ref<Scope *()> EnterScope);
void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record);
void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param);
@@ -6630,7 +6937,7 @@ public:
bool IgnoreAccess = false);
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
unsigned InaccessibleBaseID,
- unsigned AmbigiousBaseConvID,
+ unsigned AmbiguousBaseConvID,
SourceLocation Loc, SourceRange Range,
DeclarationName Name,
CXXCastPath *BasePath,
@@ -6658,7 +6965,7 @@ public:
/// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was
/// not used in the declaration of an overriding method.
- void DiagnoseAbsenceOfOverrideControl(NamedDecl *D);
+ void DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent);
/// CheckForFunctionMarkedFinal - Checks whether a virtual member function
/// overrides a virtual member function marked 'final', according to
@@ -6802,6 +7109,27 @@ public:
bool AllowFunctionTemplates = true,
bool AllowDependent = true);
+ enum TemplateNameIsRequiredTag { TemplateNameIsRequired };
+ /// Whether and why a template name is required in this lookup.
+ class RequiredTemplateKind {
+ public:
+ /// Template name is required if TemplateKWLoc is valid.
+ RequiredTemplateKind(SourceLocation TemplateKWLoc = SourceLocation())
+ : TemplateKW(TemplateKWLoc) {}
+ /// Template name is unconditionally required.
+ RequiredTemplateKind(TemplateNameIsRequiredTag) : TemplateKW() {}
+
+ SourceLocation getTemplateKeywordLoc() const {
+ return TemplateKW.getValueOr(SourceLocation());
+ }
+ bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
+ bool isRequired() const { return TemplateKW != SourceLocation(); }
+ explicit operator bool() const { return isRequired(); }
+
+ private:
+ llvm::Optional<SourceLocation> TemplateKW;
+ };
+
enum class AssumedTemplateKind {
/// This is not assumed to be a template name.
None,
@@ -6811,11 +7139,11 @@ public:
/// functions (but no function templates).
FoundFunctions,
};
- bool LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
- QualType ObjectType, bool EnteringContext,
- bool &MemberOfUnknownSpecialization,
- SourceLocation TemplateKWLoc = SourceLocation(),
- AssumedTemplateKind *ATK = nullptr);
+ bool LookupTemplateName(
+ LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType,
+ bool EnteringContext, bool &MemberOfUnknownSpecialization,
+ RequiredTemplateKind RequiredTemplate = SourceLocation(),
+ AssumedTemplateKind *ATK = nullptr, bool AllowTypoCorrection = true);
TemplateNameKind isTemplateName(Scope *S,
CXXScopeSpec &SS,
@@ -6824,7 +7152,8 @@ public:
ParsedType ObjectType,
bool EnteringContext,
TemplateTy &Template,
- bool &MemberOfUnknownSpecialization);
+ bool &MemberOfUnknownSpecialization,
+ bool Disambiguation = false);
/// Try to resolve an undeclared template name as a type template.
///
@@ -6873,7 +7202,8 @@ public:
SourceLocation EqualLoc,
ParsedType DefaultArg, bool HasTypeConstraint);
- bool ActOnTypeConstraint(TemplateIdAnnotation *TypeConstraint,
+ bool ActOnTypeConstraint(const CXXScopeSpec &SS,
+ TemplateIdAnnotation *TypeConstraint,
TemplateTypeParmDecl *ConstrainedParameter,
SourceLocation EllipsisLoc);
@@ -6884,6 +7214,10 @@ public:
TemplateTypeParmDecl *ConstrainedParameter,
SourceLocation EllipsisLoc);
+ bool AttachTypeConstraint(AutoTypeLoc TL,
+ NonTypeTemplateParmDecl *ConstrainedParameter,
+ SourceLocation EllipsisLoc);
+
QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI,
SourceLocation Loc);
QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
@@ -6933,7 +7267,8 @@ public:
SourceLocation DeclStartLoc, SourceLocation DeclLoc,
const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId,
ArrayRef<TemplateParameterList *> ParamLists,
- bool IsFriend, bool &IsMemberSpecialization, bool &Invalid);
+ bool IsFriend, bool &IsMemberSpecialization, bool &Invalid,
+ bool SuppressDiagnostic = false);
DeclResult CheckClassTemplate(
Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
@@ -6951,7 +7286,7 @@ public:
/// Get a template argument mapping the given template parameter to itself,
/// e.g. for X in \c template<int X>, this would return an expression template
/// argument referencing X.
- TemplateArgumentLoc getIdentityTemplateArgumentLoc(Decl *Param,
+ TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param,
SourceLocation Location);
void translateTemplateArguments(const ASTTemplateArgsPtr &In,
@@ -7021,15 +7356,15 @@ public:
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs);
- TemplateNameKind ActOnDependentTemplateName(
+ TemplateNameKind ActOnTemplateName(
Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext,
TemplateTy &Template, bool AllowInjectedClassName = false);
DeclResult ActOnClassTemplateSpecialization(
Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
- SourceLocation ModulePrivateLoc, TemplateIdAnnotation &TemplateId,
- const ParsedAttributesView &Attr,
+ SourceLocation ModulePrivateLoc, CXXScopeSpec &SS,
+ TemplateIdAnnotation &TemplateId, const ParsedAttributesView &Attr,
MultiTemplateParamsArg TemplateParameterLists,
SkipBodyInfo *SkipBody = nullptr);
@@ -7261,7 +7596,17 @@ public:
SourceLocation KeywordLoc,
NestedNameSpecifierLoc QualifierLoc,
const IdentifierInfo &II,
- SourceLocation IILoc);
+ SourceLocation IILoc,
+ TypeSourceInfo **TSI,
+ bool DeducedTSTContext);
+
+ QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
+ SourceLocation KeywordLoc,
+ NestedNameSpecifierLoc QualifierLoc,
+ const IdentifierInfo &II,
+ SourceLocation IILoc,
+ bool DeducedTSTContext = true);
+
TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
SourceLocation Loc,
@@ -7281,11 +7626,52 @@ public:
const TemplateArgument *Args,
unsigned NumArgs);
- // Concepts
+ //===--------------------------------------------------------------------===//
+ // C++ Concepts
+ //===--------------------------------------------------------------------===//
Decl *ActOnConceptDefinition(
Scope *S, MultiTemplateParamsArg TemplateParameterLists,
IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr);
+ RequiresExprBodyDecl *
+ ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,
+ ArrayRef<ParmVarDecl *> LocalParameters,
+ Scope *BodyScope);
+ void ActOnFinishRequiresExpr();
+ concepts::Requirement *ActOnSimpleRequirement(Expr *E);
+ concepts::Requirement *ActOnTypeRequirement(
+ SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc,
+ IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId);
+ concepts::Requirement *ActOnCompoundRequirement(Expr *E,
+ SourceLocation NoexceptLoc);
+ concepts::Requirement *
+ ActOnCompoundRequirement(
+ Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS,
+ TemplateIdAnnotation *TypeConstraint, unsigned Depth);
+ concepts::Requirement *ActOnNestedRequirement(Expr *Constraint);
+ concepts::ExprRequirement *
+ BuildExprRequirement(
+ Expr *E, bool IsSatisfied, SourceLocation NoexceptLoc,
+ concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement);
+ concepts::ExprRequirement *
+ BuildExprRequirement(
+ concepts::Requirement::SubstitutionDiagnostic *ExprSubstDiag,
+ bool IsSatisfied, SourceLocation NoexceptLoc,
+ concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement);
+ concepts::TypeRequirement *BuildTypeRequirement(TypeSourceInfo *Type);
+ concepts::TypeRequirement *
+ BuildTypeRequirement(
+ concepts::Requirement::SubstitutionDiagnostic *SubstDiag);
+ concepts::NestedRequirement *BuildNestedRequirement(Expr *E);
+ concepts::NestedRequirement *
+ BuildNestedRequirement(
+ concepts::Requirement::SubstitutionDiagnostic *SubstDiag);
+ ExprResult ActOnRequiresExpr(SourceLocation RequiresKWLoc,
+ RequiresExprBodyDecl *Body,
+ ArrayRef<ParmVarDecl *> LocalParameters,
+ ArrayRef<concepts::Requirement *> Requirements,
+ SourceLocation ClosingBraceLoc);
+
//===--------------------------------------------------------------------===//
// C++ Variadic Templates (C++0x [temp.variadic])
//===--------------------------------------------------------------------===//
@@ -7794,10 +8180,12 @@ public:
DeduceAutoResult
DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result,
- Optional<unsigned> DependentDeductionDepth = None);
+ Optional<unsigned> DependentDeductionDepth = None,
+ bool IgnoreConstraints = false);
DeduceAutoResult
DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result,
- Optional<unsigned> DependentDeductionDepth = None);
+ Optional<unsigned> DependentDeductionDepth = None,
+ bool IgnoreConstraints = false);
void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
bool Diagnose = true);
@@ -7822,12 +8210,10 @@ public:
SourceLocation ReturnLoc,
Expr *&RetExpr, AutoType *AT);
- FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- unsigned NumCallArguments2);
+ FunctionTemplateDecl *getMoreSpecializedTemplate(
+ FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
+ TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
+ unsigned NumCallArguments2, bool Reversed = false);
UnresolvedSetIterator
getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
TemplateSpecCandidateSet &FailedCandidates,
@@ -7932,6 +8318,13 @@ public:
/// template which was deferred until it was needed.
ExceptionSpecInstantiation,
+ /// We are instantiating a requirement of a requires expression.
+ RequirementInstantiation,
+
+ /// We are checking the satisfaction of a nested requirement of a requires
+ /// expression.
+ NestedRequirementConstraintsCheck,
+
/// We are declaring an implicit special member function.
DeclaringSpecialMember,
@@ -7962,6 +8355,12 @@ public:
/// We are rewriting a comparison operator in terms of an operator<=>.
RewritingOperatorAsSpaceship,
+ /// We are initializing a structured binding.
+ InitializingStructuredBinding,
+
+ /// We are marking a class as __dllexport.
+ MarkingClassDllexported,
+
/// Added for Template instantiation observation.
/// Memoization means we are _not_ instantiating a template because
/// it is already instantiated (but we entered a context where we
@@ -8253,6 +8652,19 @@ public:
ParameterMappingSubstitution, NamedDecl *Template,
SourceRange InstantiationRange);
+ /// \brief Note that we are substituting template arguments into a part of
+ /// a requirement of a requires expression.
+ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ concepts::Requirement *Req,
+ sema::TemplateDeductionInfo &DeductionInfo,
+ SourceRange InstantiationRange = SourceRange());
+
+ /// \brief Note that we are checking the satisfaction of the constraint
+ /// expression inside of a nested requirement.
+ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ concepts::NestedRequirement *Req, ConstraintsCheck,
+ SourceRange InstantiationRange = SourceRange());
+
/// Note that we have finished instantiating this template.
void Clear();
@@ -8451,9 +8863,17 @@ public:
S.VTableUses.swap(SavedVTableUses);
// Restore the set of pending implicit instantiations.
- assert(S.PendingInstantiations.empty() &&
- "PendingInstantiations should be empty before it is discarded.");
- S.PendingInstantiations.swap(SavedPendingInstantiations);
+ if (S.TUKind != TU_Prefix || !S.LangOpts.PCHInstantiateTemplates) {
+ assert(S.PendingInstantiations.empty() &&
+ "PendingInstantiations should be empty before it is discarded.");
+ S.PendingInstantiations.swap(SavedPendingInstantiations);
+ } else {
+ // Template instantiations in the PCH may be delayed until the TU.
+ S.PendingInstantiations.swap(SavedPendingInstantiations);
+ S.PendingInstantiations.insert(S.PendingInstantiations.end(),
+ SavedPendingInstantiations.begin(),
+ SavedPendingInstantiations.end());
+ }
}
private:
@@ -8682,6 +9102,8 @@ public:
TemplateArgumentListInfo &Result,
const MultiLevelTemplateArgumentList &TemplateArgs);
+ bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD,
+ ParmVarDecl *Param);
void InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
FunctionDecl *Function);
bool CheckInstantiatedFunctionTemplateConstraints(
@@ -9124,8 +9546,8 @@ public:
QualType DestType, QualType SrcType,
Expr *&SrcExpr, bool Diagnose = true);
- bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr,
- bool Diagnose = true);
+ bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr,
+ bool Diagnose = true);
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
@@ -9235,6 +9657,18 @@ public:
void ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name,
StringRef Value);
+ /// Are precise floating point semantics currently enabled?
+ bool isPreciseFPEnabled() {
+ return !CurFPFeatures.getAllowFPReassociate() &&
+ !CurFPFeatures.getNoSignedZero() &&
+ !CurFPFeatures.getAllowReciprocal() &&
+ !CurFPFeatures.getAllowApproxFunc();
+ }
+
+ /// ActOnPragmaFloatControl - Call on well-formed \#pragma float_control
+ void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action,
+ PragmaFloatControlKind Value);
+
/// ActOnPragmaUnused - Called on well-formed '\#pragma unused'.
void ActOnPragmaUnused(const Token &Identifier,
Scope *curScope,
@@ -9271,11 +9705,21 @@ public:
/// ActOnPragmaFPContract - Called on well formed
/// \#pragma {STDC,OPENCL} FP_CONTRACT and
/// \#pragma clang fp contract
- void ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC);
+ void ActOnPragmaFPContract(SourceLocation Loc, LangOptions::FPModeKind FPC);
+
+ /// Called on well formed
+ /// \#pragma clang fp reassociate
+ void ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled);
/// ActOnPragmaFenvAccess - Called on well formed
/// \#pragma STDC FENV_ACCESS
- void ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC);
+ void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled);
+
+ /// Called to set rounding mode for floating point operations.
+ void setRoundingMode(SourceLocation Loc, llvm::RoundingMode);
+
+ /// Called to set exception behavior for floating point operations.
+ void setExceptionMode(SourceLocation Loc, LangOptions::FPExceptionModeKind);
/// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
/// a the record decl, to handle '\#pragma pack' and '\#pragma options align'.
@@ -9413,6 +9857,9 @@ public:
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
ClassTemplateDecl *lookupCoroutineTraits(SourceLocation KwLoc,
SourceLocation FuncLoc);
+ /// Check that the expression co_await promise.final_suspend() shall not be
+ /// potentially-throwing.
+ bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend);
//===--------------------------------------------------------------------===//
// OpenCL extensions.
@@ -9443,7 +9890,7 @@ public:
std::string getOpenCLExtensionsFromExtMap(T* FT, MapT &Map);
void setCurrentOpenCLExtension(llvm::StringRef Ext) {
- CurrOpenCLExtension = Ext;
+ CurrOpenCLExtension = std::string(Ext);
}
/// Set OpenCL extensions for a type which can only be used when these
@@ -9511,22 +9958,6 @@ private:
/// Pop OpenMP function region for non-capturing function.
void popOpenMPFunctionRegion(const sema::FunctionScopeInfo *OldFSI);
- /// Check whether we're allowed to call Callee from the current function.
- void checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee,
- bool CheckForDelayedContext = true);
-
- /// Check whether we're allowed to call Callee from the current function.
- void checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee,
- bool CheckCaller = true);
-
- /// Check if the expression is allowed to be used in expressions for the
- /// OpenMP devices.
- void checkOpenMPDeviceExpr(const Expr *E);
-
- /// Finishes analysis of the deferred functions calls that may be declared as
- /// host/nohost during device/host compilation.
- void finalizeOpenMPDelayedAnalysis();
-
/// Checks if a type or a declaration is disabled due to the owning extension
/// being disabled, and emits diagnostic messages if it is disabled.
/// \param D type or declaration to be checked.
@@ -9542,17 +9973,54 @@ private:
MapT &Map, unsigned Selector = 0,
SourceRange SrcRange = SourceRange());
- /// Marks all the functions that might be required for the currently active
- /// OpenMP context.
- void markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc,
- FunctionDecl *Func,
- bool MightBeOdrUse);
+ /// Helper to keep information about the current `omp begin/end declare
+ /// variant` nesting.
+ struct OMPDeclareVariantScope {
+ /// The associated OpenMP context selector.
+ OMPTraitInfo *TI;
+
+ /// The associated OpenMP context selector mangling.
+ std::string NameSuffix;
+
+ OMPDeclareVariantScope(OMPTraitInfo &TI);
+ };
+
+ /// The current `omp begin/end declare variant` scopes.
+ SmallVector<OMPDeclareVariantScope, 4> OMPDeclareVariantScopes;
+
+ /// The declarator \p D defines a function in the scope \p S which is nested
+ /// in an `omp begin/end declare variant` scope. In this method we create a
+ /// declaration for \p D and rename \p D according to the OpenMP context
+ /// selector of the surrounding scope.
+ FunctionDecl *
+ ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S,
+ Declarator &D);
+
+ /// Register \p FD as specialization of \p BaseFD in the current `omp
+ /// begin/end declare variant` scope.
+ void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
+ FunctionDecl *FD, FunctionDecl *BaseFD);
public:
- /// Struct to store the context selectors info for declare variant directive.
- using OMPCtxStringType = SmallString<8>;
- using OMPCtxSelectorData =
- OpenMPCtxSelectorData<SmallVector<OMPCtxStringType, 4>, ExprResult>;
+
+ /// Can we exit a scope at the moment.
+ bool isInOpenMPDeclareVariantScope() {
+ return !OMPDeclareVariantScopes.empty();
+ }
+
+ /// Given the potential call expression \p Call, determine if there is a
+ /// specialization via the OpenMP declare variant mechanism available. If
+ /// there is, return the specialized call expression, otherwise return the
+ /// original \p Call.
+ ExprResult ActOnOpenMPCall(ExprResult Call, Scope *Scope,
+ SourceLocation LParenLoc, MultiExprArg ArgExprs,
+ SourceLocation RParenLoc, Expr *ExecConfig);
+
+ /// Handle a `omp begin declare variant`.
+ void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI);
+
+ /// Handle a `omp end declare variant`.
+ void ActOnOpenMPEndDeclareVariant();
/// Checks if the variant/multiversion functions are compatible.
bool areMultiversionVariantFunctionsCompatible(
@@ -9594,7 +10062,8 @@ public:
/// Check if the specified variable is used in 'private' clause.
/// \param Level Relative level of nested OpenMP construct for that the check
/// is performed.
- bool isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const;
+ OpenMPClauseKind isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
+ unsigned CapLevel) const;
/// Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.)
/// for \p FD based on DSA for the provided corresponding captured declaration
@@ -9604,7 +10073,15 @@ public:
/// Check if the specified variable is captured by 'target' directive.
/// \param Level Relative level of nested OpenMP construct for that the check
/// is performed.
- bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level) const;
+ bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
+ unsigned CaptureLevel) const;
+
+ /// Check if the specified global variable must be captured by outer capture
+ /// regions.
+ /// \param Level Relative level of nested OpenMP construct for that
+ /// the check is performed.
+ bool isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
+ unsigned CaptureLevel) const;
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc,
Expr *Op);
@@ -9711,6 +10188,11 @@ public:
void
checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
SourceLocation IdLoc = SourceLocation());
+ /// Finishes analysis of the deferred functions calls that may be declared as
+ /// host/nohost during device/host compilation.
+ void finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
+ const FunctionDecl *Callee,
+ SourceLocation Loc);
/// Return true inside OpenMP declare target region.
bool isInOpenMPDeclareTargetContext() const {
return DeclareTargetNestingLevel > 0;
@@ -9828,6 +10310,14 @@ public:
StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed '\#pragma omp depobj'.
+ StmtResult ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// Called on well-formed '\#pragma omp scan'.
+ StmtResult ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc);
/// Called on well-formed '\#pragma omp ordered' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
@@ -10007,7 +10497,8 @@ public:
/// Checks that the specified declaration matches requirements for the linear
/// decls.
bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
- OpenMPLinearClauseKind LinKind, QualType Type);
+ OpenMPLinearClauseKind LinKind, QualType Type,
+ bool IsDeclareSimd = false);
/// Called on well-formed '\#pragma omp declare simd' after parsing of
/// the associated method/function.
@@ -10023,10 +10514,12 @@ public:
/// applied to.
/// \param VariantRef Expression that references the variant function, which
/// must be used instead of the original one, specified in \p DG.
+ /// \param TI The trait info object representing the match clause.
/// \returns None, if the function/variant function are not compatible with
/// the pragma, pair of original function/variant ref expression otherwise.
- Optional<std::pair<FunctionDecl *, Expr *>> checkOpenMPDeclareVariantFunction(
- DeclGroupPtrTy DG, Expr *VariantRef, SourceRange SR);
+ Optional<std::pair<FunctionDecl *, Expr *>>
+ checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef,
+ OMPTraitInfo &TI, SourceRange SR);
/// Called on well-formed '\#pragma omp declare variant' after parsing of
/// the associated method/function.
@@ -10034,11 +10527,9 @@ public:
/// applied to.
/// \param VariantRef Expression that references the variant function, which
/// must be used instead of the original one, specified in \p DG.
- /// \param Data Set of context-specific data for the specified context
- /// selector.
+ /// \param TI The context traits associated with the function variant.
void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef,
- SourceRange SR,
- ArrayRef<OMPCtxSelectorData> Data);
+ OMPTraitInfo &TI, SourceRange SR);
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
Expr *Expr,
@@ -10097,6 +10588,10 @@ public:
OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'detach' clause.
+ OMPClause *ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
unsigned Argument,
@@ -10105,7 +10600,7 @@ public:
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// Called on well-formed 'default' clause.
- OMPClause *ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
+ OMPClause *ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind,
SourceLocation KindLoc,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -10116,6 +10611,18 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'order' clause.
+ OMPClause *ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
+ SourceLocation KindLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+ /// Called on well-formed 'update' clause.
+ OMPClause *ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
+ SourceLocation KindLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
OMPClause *ActOnOpenMPSingleExprWithArgClause(
OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr,
@@ -10155,6 +10662,21 @@ public:
/// Called on well-formed 'seq_cst' clause.
OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'acq_rel' clause.
+ OMPClause *ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// Called on well-formed 'acquire' clause.
+ OMPClause *ActOnOpenMPAcquireClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// Called on well-formed 'release' clause.
+ OMPClause *ActOnOpenMPReleaseClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// Called on well-formed 'relaxed' clause.
+ OMPClause *ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// Called on well-formed 'destroy' clause.
+ OMPClause *ActOnOpenMPDestroyClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
/// Called on well-formed 'threads' clause.
OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc,
SourceLocation EndLoc);
@@ -10186,13 +10708,23 @@ public:
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
OMPClause *ActOnOpenMPVarListClause(
- OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr,
+ OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *DepModOrTailExpr,
const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
CXXScopeSpec &ReductionOrMapperIdScopeSpec,
DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
- SourceLocation DepLinMapLastLoc);
+ SourceLocation ExtraModifierLoc);
+ /// Called on well-formed 'inclusive' clause.
+ OMPClause *ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+ /// Called on well-formed 'exclusive' clause.
+ OMPClause *ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// Called on well-formed 'allocate' clause.
OMPClause *
ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList,
@@ -10220,9 +10752,10 @@ public:
SourceLocation EndLoc);
/// Called on well-formed 'reduction' clause.
OMPClause *ActOnOpenMPReductionClause(
- ArrayRef<Expr *> VarList, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
- CXXScopeSpec &ReductionIdScopeSpec,
+ ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ModifierLoc, SourceLocation ColonLoc,
+ SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId,
ArrayRef<Expr *> UnresolvedReductions = llvm::None);
/// Called on well-formed 'task_reduction' clause.
@@ -10267,15 +10800,21 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'depobj' pseudo clause.
+ OMPClause *ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// Called on well-formed 'depend' clause.
OMPClause *
- ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc,
- SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc);
+ ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
+ SourceLocation DepLoc, SourceLocation ColonLoc,
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc);
/// Called on well-formed 'device' clause.
- OMPClause *ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
+ OMPClause *ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
+ Expr *Device, SourceLocation StartLoc,
SourceLocation LParenLoc,
+ SourceLocation ModifierLoc,
SourceLocation EndLoc);
/// Called on well-formed 'map' clause.
OMPClause *
@@ -10324,6 +10863,9 @@ public:
/// Called on well-formed 'use_device_ptr' clause.
OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
const OMPVarListLocTy &Locs);
+ /// Called on well-formed 'use_device_addr' clause.
+ OMPClause *ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
+ const OMPVarListLocTy &Locs);
/// Called on well-formed 'is_device_ptr' clause.
OMPClause *ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
const OMPVarListLocTy &Locs);
@@ -10333,6 +10875,27 @@ public:
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// Data for list of allocators.
+ struct UsesAllocatorsData {
+ /// Allocator.
+ Expr *Allocator = nullptr;
+ /// Allocator traits.
+ Expr *AllocatorTraits = nullptr;
+ /// Locations of '(' and ')' symbols.
+ SourceLocation LParenLoc, RParenLoc;
+ };
+ /// Called on well-formed 'uses_allocators' clause.
+ OMPClause *ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<UsesAllocatorsData> Data);
+ /// Called on well-formed 'affinity' clause.
+ OMPClause *ActOnOpenMPAffinityClause(SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc, Expr *Modifier,
+ ArrayRef<Expr *> Locators);
+
/// The kind of conversion being performed.
enum CheckedConversionKind {
/// An implicit conversion.
@@ -10389,9 +10952,8 @@ public:
bool Diagnose = true);
// DefaultLvalueConversion - performs lvalue-to-rvalue conversion on
- // the operand. This is DefaultFunctionArrayLvalueConversion,
- // except that it assumes the operand isn't of function or array
- // type.
+ // the operand. This function is a no-op if the operand has a function type
+ // or an array type.
ExprResult DefaultLvalueConversion(Expr *E);
// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
@@ -10499,6 +11061,11 @@ public:
/// are not compatible, but we accept them as an extension.
IncompatiblePointer,
+ /// IncompatibleFunctionPointer - The assignment is between two function
+ /// pointers types that are not compatible, but we accept them as an
+ /// extension.
+ IncompatibleFunctionPointer,
+
/// IncompatiblePointerSign - The assignment is between two pointers types
/// which point to integers which have a different sign, but are otherwise
/// identical. This is a subset of the above, but broken out because it's by
@@ -10728,6 +11295,13 @@ public:
QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc);
+ /// Type checking for matrix binary operators.
+ QualType CheckMatrixElementwiseOperands(ExprResult &LHS, ExprResult &RHS,
+ SourceLocation Loc,
+ bool IsCompAssign);
+ QualType CheckMatrixMultiplyOperands(ExprResult &LHS, ExprResult &RHS,
+ SourceLocation Loc, bool IsCompAssign);
+
bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType);
bool isLaxVectorConversion(QualType srcType, QualType destType);
@@ -11041,18 +11615,6 @@ public:
/* Caller = */ FunctionDeclAndLoc>
DeviceKnownEmittedFns;
- /// A partial call graph maintained during CUDA/OpenMP device code compilation
- /// to support deferred diagnostics.
- ///
- /// Functions are only added here if, at the time they're considered, they are
- /// not known-emitted. As soon as we discover that a function is
- /// known-emitted, we remove it and everything it transitively calls from this
- /// set and add those functions to DeviceKnownEmittedFns.
- llvm::DenseMap</* Caller = */ CanonicalDeclPtr<FunctionDecl>,
- /* Callees = */ llvm::MapVector<CanonicalDeclPtr<FunctionDecl>,
- SourceLocation>>
- DeviceCallGraph;
-
/// Diagnostic builder for CUDA/OpenMP devices errors which may or may not be
/// deferred.
///
@@ -11127,14 +11689,6 @@ public:
llvm::Optional<unsigned> PartialDiagId;
};
- /// Indicate that this function (and thus everything it transtively calls)
- /// will be codegen'ed, and emit any deferred diagnostics on this function and
- /// its (transitive) callees.
- void markKnownEmitted(
- Sema &S, FunctionDecl *OrigCaller, FunctionDecl *OrigCallee,
- SourceLocation OrigLoc,
- const llvm::function_ref<bool(Sema &, FunctionDecl *)> IsKnownEmitted);
-
/// Creates a DeviceDiagBuilder that emits the diagnostic if the current context
/// is "used as device code".
///
@@ -11193,6 +11747,10 @@ public:
DeviceDiagBuilder targetDiag(SourceLocation Loc, unsigned DiagID);
+ /// Check if the expression is allowed to be used in expressions for the
+ /// offloading devices.
+ void checkDeviceDecl(const ValueDecl *D, SourceLocation Loc);
+
enum CUDAFunctionTarget {
CFT_Device,
CFT_Global,
@@ -11215,6 +11773,8 @@ public:
return IdentifyCUDATarget(dyn_cast<FunctionDecl>(CurContext));
}
+ static bool isCUDAImplicitHostDeviceFunction(const FunctionDecl *D);
+
// CUDA function call preference. Must be ordered numerically from
// worst to best.
enum CUDAFunctionPreference {
@@ -11253,6 +11813,10 @@ public:
void maybeAddCUDAHostDeviceAttrs(FunctionDecl *FD,
const LookupResult &Previous);
+ /// May add implicit CUDAConstantAttr attribute to VD, depending on VD
+ /// and current compilation settings.
+ void MaybeAddCUDAConstantAttr(VarDecl *VD);
+
public:
/// Check whether we're allowed to call Callee from the current context.
///
@@ -11270,12 +11834,13 @@ public:
/// - Otherwise, returns true without emitting any diagnostics.
bool CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee);
+ void CUDACheckLambdaCapture(CXXMethodDecl *D, const sema::Capture &Capture);
+
/// Set __device__ or __host__ __device__ attributes on the given lambda
/// operator() method.
///
- /// CUDA lambdas declared inside __device__ or __global__ functions inherit
- /// the __device__ attribute. Similarly, lambdas inside __host__ __device__
- /// functions become __host__ __device__ themselves.
+ /// CUDA lambdas by default is host device function unless it has explicit
+ /// host or device attribute.
void CUDASetLambdaAttrs(CXXMethodDecl *Method);
/// Finds a function in \p Matches with highest calling priority
@@ -11416,7 +11981,13 @@ public:
IdentifierInfo *II,
SourceLocation OpenParLoc);
void CodeCompleteInitializer(Scope *S, Decl *D);
- void CodeCompleteAfterIf(Scope *S);
+ /// Trigger code completion for a record of \p BaseType. \p InitExprs are
+ /// expressions in the initializer list seen so far and \p D is the current
+ /// Designation being parsed.
+ void CodeCompleteDesignator(const QualType BaseType,
+ llvm::ArrayRef<Expr *> InitExprs,
+ const Designation &D);
+ void CodeCompleteAfterIf(Scope *S, bool IsBracedThen);
void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext,
bool IsUsingDeclaration, QualType BaseType,
@@ -11432,6 +12003,7 @@ public:
void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
bool AfterAmpersand);
+ void CodeCompleteAfterFunctionEquals(Declarator &D);
void CodeCompleteObjCAtDirective(Scope *S);
void CodeCompleteObjCAtVisibility(Scope *S);
@@ -11545,27 +12117,50 @@ private:
ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl,
unsigned BuiltinID, CallExpr *TheCall);
+
+ bool CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
+ CallExpr *TheCall);
+
void checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, CallExpr *TheCall);
bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
unsigned MaxWidth);
- bool CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
+ CallExpr *TheCall);
bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
-
- bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
+ CallExpr *TheCall);
+ bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg,
+ bool WantCDE);
+ bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
+ CallExpr *TheCall);
+
+ bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
+ CallExpr *TheCall);
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckHexagonBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall);
bool CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckMipsBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
+ CallExpr *TheCall);
+ bool CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID,
+ CallExpr *TheCall);
bool CheckMipsBuiltinArgument(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);
+ bool CheckX86BuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall,
+ ArrayRef<int> ArgNums);
+ bool CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, int ArgNum);
+ bool CheckX86BuiltinTileDuplicate(CallExpr *TheCall, ArrayRef<int> ArgNums);
+ bool CheckX86BuiltinTileRangeAndDuplicate(CallExpr *TheCall,
+ ArrayRef<int> ArgNums);
+ bool CheckX86BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
+ CallExpr *TheCall);
+ bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
+ CallExpr *TheCall);
+ bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall);
bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call);
@@ -11601,12 +12196,23 @@ private:
bool SemaBuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum,
unsigned Multiple);
bool SemaBuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum);
- bool SemaBuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum);
- bool SemaBuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum);
+ bool SemaBuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum,
+ unsigned ArgBits);
+ bool SemaBuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum,
+ unsigned ArgBits);
bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall,
int ArgNum, unsigned ExpectedFieldNum,
bool AllowName);
bool SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall);
+
+ // Matrix builtin handling.
+ ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall,
+ ExprResult CallResult);
+ ExprResult SemaBuiltinMatrixColumnMajorLoad(CallExpr *TheCall,
+ ExprResult CallResult);
+ ExprResult SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall,
+ ExprResult CallResult);
+
public:
enum FormatStringType {
FST_Scanf,
@@ -11805,6 +12411,13 @@ public:
return DC;
}
+ /// Determine the number of levels of enclosing template parameters. This is
+ /// only usable while parsing. Note that this does not include dependent
+ /// contexts in which no template parameters have yet been declared, such as
+ /// in a terse function template or generic lambda before the first 'auto' is
+ /// encountered.
+ unsigned getTemplateDepth(Scope *S) const;
+
/// To be used for checking whether the arguments being passed to
/// function exceeds the number of parameters expected for it.
static bool TooManyArguments(size_t NumParams, size_t NumArgs,
@@ -11904,6 +12517,40 @@ public:
ConstructorDestructor,
BuiltinFunction
};
+ /// Creates a DeviceDiagBuilder that emits the diagnostic if the current
+ /// context is "used as device code".
+ ///
+ /// - If CurLexicalContext is a kernel function or it is known that the
+ /// function will be emitted for the device, emits the diagnostics
+ /// immediately.
+ /// - If CurLexicalContext is a function and we are compiling
+ /// for the device, but we don't know that this function will be codegen'ed
+ /// for devive yet, creates a diagnostic which is emitted if and when we
+ /// realize that the function will be codegen'ed.
+ ///
+ /// Example usage:
+ ///
+ /// Diagnose __float128 type usage only from SYCL device code if the current
+ /// target doesn't support it
+ /// if (!S.Context.getTargetInfo().hasFloat128Type() &&
+ /// S.getLangOpts().SYCLIsDevice)
+ /// SYCLDiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128";
+ DeviceDiagBuilder SYCLDiagIfDeviceCode(SourceLocation Loc, unsigned DiagID);
+
+ /// Check whether we're allowed to call Callee from the current context.
+ ///
+ /// - If the call is never allowed in a semantically-correct program
+ /// emits an error and returns false.
+ ///
+ /// - If the call is allowed in semantically-correct programs, but only if
+ /// it's never codegen'ed, creates a deferred diagnostic to be emitted if
+ /// and when the caller is codegen'ed, and returns true.
+ ///
+ /// - Otherwise, returns true without emitting any diagnostics.
+ ///
+ /// Adds Callee to DeviceCallGraph if we don't know if its caller will be
+ /// codegen'ed yet.
+ bool checkSYCLDeviceFunction(SourceLocation Loc, FunctionDecl *Callee);
};
/// RAII object that enters a new expression evaluation context.