aboutsummaryrefslogtreecommitdiff
path: root/clang/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/AST')
-rw-r--r--clang/include/clang/AST/APValue.h2
-rw-r--r--clang/include/clang/AST/ASTConcept.h33
-rw-r--r--clang/include/clang/AST/ASTContext.h242
-rw-r--r--clang/include/clang/AST/ASTDumper.h18
-rw-r--r--clang/include/clang/AST/ASTDumperUtils.h2
-rw-r--r--clang/include/clang/AST/ASTFwd.h4
-rw-r--r--clang/include/clang/AST/ASTImporter.h5
-rw-r--r--clang/include/clang/AST/ASTNodeTraverser.h47
-rw-r--r--clang/include/clang/AST/ASTTypeTraits.h48
-rw-r--r--clang/include/clang/AST/Attr.h5
-rw-r--r--clang/include/clang/AST/BuiltinTypes.def14
-rw-r--r--clang/include/clang/AST/CXXInheritance.h6
-rw-r--r--clang/include/clang/AST/CXXRecordDeclDefinitionBits.def2
-rw-r--r--clang/include/clang/AST/CanonicalType.h6
-rw-r--r--clang/include/clang/AST/Comment.h4
-rw-r--r--clang/include/clang/AST/CommentCommands.td2
-rw-r--r--clang/include/clang/AST/CommentSema.h3
-rw-r--r--clang/include/clang/AST/ComputeDependence.h194
-rw-r--r--clang/include/clang/AST/DataCollection.h7
-rw-r--r--clang/include/clang/AST/Decl.h91
-rw-r--r--clang/include/clang/AST/DeclBase.h62
-rw-r--r--clang/include/clang/AST/DeclCXX.h193
-rw-r--r--clang/include/clang/AST/DeclGroup.h2
-rw-r--r--clang/include/clang/AST/DeclObjC.h97
-rw-r--r--clang/include/clang/AST/DeclObjCCommon.h55
-rw-r--r--clang/include/clang/AST/DeclOpenMP.h4
-rw-r--r--clang/include/clang/AST/DeclTemplate.h51
-rw-r--r--clang/include/clang/AST/DependenceFlags.h284
-rw-r--r--clang/include/clang/AST/Expr.h968
-rw-r--r--clang/include/clang/AST/ExprCXX.h532
-rw-r--r--clang/include/clang/AST/ExprConcepts.h554
-rw-r--r--clang/include/clang/AST/ExprObjC.h168
-rw-r--r--clang/include/clang/AST/ExprOpenMP.h351
-rw-r--r--clang/include/clang/AST/ExternalASTSource.h32
-rw-r--r--clang/include/clang/AST/GlobalDecl.h58
-rw-r--r--clang/include/clang/AST/JSONNodeDumper.h6
-rw-r--r--clang/include/clang/AST/LocInfoType.h5
-rw-r--r--clang/include/clang/AST/Mangle.h22
-rw-r--r--clang/include/clang/AST/NestedNameSpecifier.h6
-rw-r--r--clang/include/clang/AST/NonTrivialTypeVisitor.h2
-rw-r--r--clang/include/clang/AST/ODRHash.h2
-rw-r--r--clang/include/clang/AST/OpenMPClause.h1748
-rw-r--r--clang/include/clang/AST/ParentMapContext.h144
-rw-r--r--clang/include/clang/AST/PrettyPrinter.h18
-rw-r--r--clang/include/clang/AST/PropertiesBase.td2
-rw-r--r--clang/include/clang/AST/RawCommentList.h21
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h447
-rw-r--r--clang/include/clang/AST/Stmt.h145
-rw-r--r--clang/include/clang/AST/StmtOpenMP.h343
-rw-r--r--clang/include/clang/AST/StmtVisitor.h1
-rw-r--r--clang/include/clang/AST/TemplateBase.h21
-rw-r--r--clang/include/clang/AST/TemplateName.h5
-rw-r--r--clang/include/clang/AST/TextNodeDumper.h35
-rw-r--r--clang/include/clang/AST/Type.h713
-rw-r--r--clang/include/clang/AST/TypeLoc.h207
-rw-r--r--clang/include/clang/AST/TypeLocVisitor.h1
-rw-r--r--clang/include/clang/AST/TypeProperties.td92
-rw-r--r--clang/include/clang/AST/VTableBuilder.h37
58 files changed, 6195 insertions, 1974 deletions
diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h
index 63359294ef63..cca92b5f8235 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -372,7 +372,7 @@ public:
bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
void dump() const;
- void dump(raw_ostream &OS) const;
+ void dump(raw_ostream &OS, const ASTContext &Context) const;
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
diff --git a/clang/include/clang/AST/ASTConcept.h b/clang/include/clang/AST/ASTConcept.h
index 896d857d8c96..71bf14a87865 100644
--- a/clang/include/clang/AST/ASTConcept.h
+++ b/clang/include/clang/AST/ASTConcept.h
@@ -22,10 +22,25 @@
#include <utility>
namespace clang {
class ConceptDecl;
+class ConceptSpecializationExpr;
+
+/// The result of a constraint satisfaction check, containing the necessary
+/// information to diagnose an unsatisfied constraint.
+class ConstraintSatisfaction : public llvm::FoldingSetNode {
+ // The template-like entity that 'owns' the constraint checked here (can be a
+ // constrained entity or a concept).
+ const NamedDecl *ConstraintOwner = nullptr;
+ llvm::SmallVector<TemplateArgument, 4> TemplateArgs;
+
+public:
+
+ ConstraintSatisfaction() = default;
+
+ ConstraintSatisfaction(const NamedDecl *ConstraintOwner,
+ ArrayRef<TemplateArgument> TemplateArgs) :
+ ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs.begin(),
+ TemplateArgs.end()) { }
-/// \brief The result of a constraint satisfaction check, containing the
-/// necessary information to diagnose an unsatisfied constraint.
-struct ConstraintSatisfaction {
using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;
@@ -37,9 +52,13 @@ struct ConstraintSatisfaction {
/// invalid expression.
llvm::SmallVector<std::pair<const Expr *, Detail>, 4> Details;
- // This can leak if used in an AST node, use ASTConstraintSatisfaction
- // instead.
- void *operator new(size_t bytes, ASTContext &C) = delete;
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
+ Profile(ID, C, ConstraintOwner, TemplateArgs);
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
+ const NamedDecl *ConstraintOwner,
+ ArrayRef<TemplateArgument> TemplateArgs);
};
/// Pairs of unsatisfied atomic constraint expressions along with the
@@ -174,4 +193,4 @@ public:
} // clang
-#endif // LLVM_CLANG_AST_ASTCONCEPT_H \ No newline at end of file
+#endif // LLVM_CLANG_AST_ASTCONCEPT_H
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index fb269cef1ce8..2b988be60da9 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -15,7 +15,7 @@
#define LLVM_CLANG_AST_ASTCONTEXT_H
#include "clang/AST/ASTContextAllocate.h"
-#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/ASTFwd.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/ComparisonCategories.h"
@@ -26,7 +26,6 @@
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RawCommentList.h"
-#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
@@ -40,7 +39,6 @@
#include "clang/Basic/SanitizerBlacklist.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/XRayLists.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
@@ -75,6 +73,7 @@
namespace llvm {
struct fltSemantics;
+template <typename T, unsigned N> class SmallPtrSet;
} // namespace llvm
@@ -88,11 +87,15 @@ class AtomicExpr;
class BlockExpr;
class BuiltinTemplateDecl;
class CharUnits;
+class ConceptDecl;
class CXXABI;
class CXXConstructorDecl;
class CXXMethodDecl;
class CXXRecordDecl;
class DiagnosticsEngine;
+class ParentMapContext;
+class DynTypedNode;
+class DynTypedNodeList;
class Expr;
class FixedPointSemantics;
class GlobalDecl;
@@ -101,6 +104,7 @@ class MangleNumberingContext;
class MaterializeTemporaryExpr;
class MemberSpecializationInfo;
class Module;
+struct MSGuidDeclParts;
class ObjCCategoryDecl;
class ObjCCategoryImplDecl;
class ObjCContainerDecl;
@@ -113,11 +117,13 @@ class ObjCPropertyDecl;
class ObjCPropertyImplDecl;
class ObjCProtocolDecl;
class ObjCTypeParamDecl;
+class OMPTraitInfo;
struct ParsedTargetAttr;
class Preprocessor;
class Stmt;
class StoredDeclsMap;
class TargetAttr;
+class TargetInfo;
class TemplateDecl;
class TemplateParameterList;
class TemplateTemplateParmDecl;
@@ -135,6 +141,7 @@ class Context;
} // namespace Builtin
enum BuiltinTemplateKind : int;
+enum OpenCLTypeKind : uint8_t;
namespace comments {
@@ -187,6 +194,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
DependentAddressSpaceTypes;
mutable llvm::FoldingSet<VectorType> VectorTypes;
mutable llvm::FoldingSet<DependentVectorType> DependentVectorTypes;
+ mutable llvm::FoldingSet<ConstantMatrixType> MatrixTypes;
+ mutable llvm::FoldingSet<DependentSizedMatrixType> DependentSizedMatrixTypes;
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
FunctionProtoTypes;
@@ -211,12 +220,14 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
mutable llvm::FoldingSet<DependentUnaryTransformType>
DependentUnaryTransformTypes;
- mutable llvm::FoldingSet<AutoType> AutoTypes;
+ mutable llvm::ContextualFoldingSet<AutoType, ASTContext&> AutoTypes;
mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
DeducedTemplateSpecializationTypes;
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
llvm::FoldingSet<AttributedType> AttributedTypes;
mutable llvm::FoldingSet<PipeType> PipeTypes;
+ mutable llvm::FoldingSet<ExtIntType> ExtIntTypes;
+ mutable llvm::FoldingSet<DependentExtIntType> DependentExtIntTypes;
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
@@ -263,6 +274,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Mapping from __block VarDecls to BlockVarCopyInit.
llvm::DenseMap<const VarDecl *, BlockVarCopyInit> BlockVarCopyInits;
+ /// Mapping from GUIDs to the corresponding MSGuidDecl.
+ mutable llvm::FoldingSet<MSGuidDecl> MSGuidDecls;
+
/// Used to cleanups APValues stored in the AST.
mutable llvm::SmallVector<APValue *, 0> APValueCleanups;
@@ -564,18 +578,9 @@ private:
const TargetInfo *AuxTarget = nullptr;
clang::PrintingPolicy PrintingPolicy;
std::unique_ptr<interp::Context> InterpContext;
-
- ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs;
+ std::unique_ptr<ParentMapContext> ParentMapCtx;
public:
- ast_type_traits::TraversalKind getTraversalKind() const { return Traversal; }
- void setTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; }
-
- const Expr *traverseIgnored(const Expr *E) const;
- Expr *traverseIgnored(Expr *E) const;
- ast_type_traits::DynTypedNode
- traverseIgnored(const ast_type_traits::DynTypedNode &N) const;
-
IdentifierTable &Idents;
SelectorTable &Selectors;
Builtin::Context &BuiltinInfo;
@@ -586,46 +591,8 @@ public:
/// Returns the clang bytecode interpreter context.
interp::Context &getInterpContext();
- /// Container for either a single DynTypedNode or for an ArrayRef to
- /// DynTypedNode. For use with ParentMap.
- class DynTypedNodeList {
- using DynTypedNode = ast_type_traits::DynTypedNode;
-
- llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode,
- ArrayRef<DynTypedNode>> Storage;
- bool IsSingleNode;
-
- public:
- DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
- new (Storage.buffer) DynTypedNode(N);
- }
-
- DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
- new (Storage.buffer) ArrayRef<DynTypedNode>(A);
- }
-
- const ast_type_traits::DynTypedNode *begin() const {
- if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
- ->begin();
- return reinterpret_cast<const DynTypedNode *>(Storage.buffer);
- }
-
- const ast_type_traits::DynTypedNode *end() const {
- if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
- ->end();
- return reinterpret_cast<const DynTypedNode *>(Storage.buffer) + 1;
- }
-
- size_t size() const { return end() - begin(); }
- bool empty() const { return begin() == end(); }
-
- const DynTypedNode &operator[](size_t N) const {
- assert(N < size() && "Out of bounds!");
- return *(begin() + N);
- }
- };
+ /// Returns the dynamic AST node parent map context.
+ ParentMapContext &getParentMapContext();
// A traversal scope limits the parts of the AST visible to certain analyses.
// RecursiveASTVisitor::TraverseAST will only visit reachable nodes, and
@@ -637,35 +604,9 @@ public:
std::vector<Decl *> getTraversalScope() const { return TraversalScope; }
void setTraversalScope(const std::vector<Decl *> &);
- /// Returns the parents of the given node (within the traversal scope).
- ///
- /// Note that this will lazily compute the parents of all nodes
- /// and store them for later retrieval. Thus, the first call is O(n)
- /// in the number of AST nodes.
- ///
- /// Caveats and FIXMEs:
- /// Calculating the parent map over all AST nodes will need to load the
- /// full AST. This can be undesirable in the case where the full AST is
- /// expensive to create (for example, when using precompiled header
- /// preambles). Thus, there are good opportunities for optimization here.
- /// One idea is to walk the given node downwards, looking for references
- /// to declaration contexts - once a declaration context is found, compute
- /// the parent map for the declaration context; if that can satisfy the
- /// request, loading the whole AST can be avoided. Note that this is made
- /// more complex by statements in templates having multiple parents - those
- /// problems can be solved by building closure over the templated parts of
- /// the AST, which also avoids touching large parts of the AST.
- /// Additionally, we will want to add an interface to already give a hint
- /// where to search for the parents, for example when looking at a statement
- /// inside a certain function.
- ///
- /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
- /// NestedNameSpecifier or NestedNameSpecifierLoc.
- template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node) {
- return getParents(ast_type_traits::DynTypedNode::create(Node));
- }
-
- DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node);
+ /// Forwards to get node parents from the ParentMapContext. New callers should
+ /// use ParentMapContext::getParents() directly.
+ template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node);
const clang::PrintingPolicy &getPrintingPolicy() const {
return PrintingPolicy;
@@ -716,7 +657,7 @@ public:
/// getRealTypeForBitwidth -
/// sets floating point QualTy according to specified bitwidth.
/// Returns empty type if there is no appropriate target types.
- QualType getRealTypeForBitwidth(unsigned DestWidth) const;
+ QualType getRealTypeForBitwidth(unsigned DestWidth, bool ExplicitIEEE) const;
bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;
@@ -790,15 +731,7 @@ public:
RawComment *getRawCommentForDeclNoCache(const Decl *D) const;
public:
- RawCommentList &getRawCommentList() {
- return Comments;
- }
-
- void addComment(const RawComment &RC) {
- assert(LangOpts.RetainCommentsFromSystemHeaders ||
- !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin()));
- Comments.addComment(RC, LangOpts.CommentOpts, BumpAlloc);
- }
+ void addComment(const RawComment &RC);
/// Return the documentation comment attached to a given declaration.
/// Returns nullptr if no comment is attached.
@@ -958,7 +891,7 @@ public:
void addedLocalImportDecl(ImportDecl *Import);
static ImportDecl *getNextLocalImport(ImportDecl *Import) {
- return Import->NextLocalImport;
+ return Import->getNextLocalImport();
}
using import_range = llvm::iterator_range<import_iterator>;
@@ -986,13 +919,7 @@ public:
/// Get the additional modules in which the definition \p Def has
/// been merged.
- ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def) {
- auto MergedIt =
- MergedDefModules.find(cast<NamedDecl>(Def->getCanonicalDecl()));
- if (MergedIt == MergedDefModules.end())
- return None;
- return MergedIt->second;
- }
+ ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def);
/// Add a declaration to the list of declarations that are initialized
/// for a module. This will typically be a global variable (with internal
@@ -1037,6 +964,7 @@ public:
CanQualType SatUnsignedShortFractTy, SatUnsignedFractTy,
SatUnsignedLongFractTy;
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
+ CanQualType BFloat16Ty;
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
CanQualType Float128ComplexTy;
@@ -1051,7 +979,8 @@ public:
#include "clang/Basic/OpenCLImageTypes.def"
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
CanQualType OCLQueueTy, OCLReserveIDTy;
- CanQualType OMPArraySectionTy;
+ CanQualType IncompleteMatrixIdxTy;
+ CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy;
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
CanQualType Id##Ty;
#include "clang/Basic/OpenCLExtensionTypes.def"
@@ -1065,7 +994,10 @@ public:
// Decl used to help define __builtin_va_list for some targets.
// The decl is built when constructing 'BuiltinVaListDecl'.
- mutable Decl *VaListTagDecl;
+ mutable Decl *VaListTagDecl = nullptr;
+
+ // Implicitly-declared type 'struct _GUID'.
+ mutable TagDecl *MSGuidTagDecl = nullptr;
ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
SelectorTable &sels, Builtin::Context &builtins);
@@ -1277,12 +1209,20 @@ public:
/// Return a write_only pipe type for the specified type.
QualType getWritePipeType(QualType T) const;
+ /// Return an extended integer type with the specified signedness and bit
+ /// count.
+ QualType getExtIntType(bool Unsigned, unsigned NumBits) const;
+
+ /// Return a dependent extended integer type with the specified signedness and
+ /// bit count.
+ QualType getDependentExtIntType(bool Unsigned, Expr *BitsExpr) const;
+
/// Gets the struct used to keep track of the extended descriptor for
/// pointer to blocks.
QualType getBlockDescriptorExtendedType() const;
/// Map an AST Type to an OpenCLTypeKind enum value.
- TargetInfo::OpenCLTypeKind getOpenCLTypeKind(const Type *T) const;
+ OpenCLTypeKind getOpenCLTypeKind(const Type *T) const;
/// Get address space for OpenCL type.
LangAS getOpenCLTypeAddrSpace(const Type *T) const;
@@ -1357,6 +1297,12 @@ public:
/// Returns a vla type where known sizes are replaced with [*].
QualType getVariableArrayDecayedType(QualType Ty) const;
+ /// Return the unique reference to a scalable vector type of the specified
+ /// element type and scalable number of elements.
+ ///
+ /// \pre \p EltTy must be a built-in type.
+ QualType getScalableVectorType(QualType EltTy, unsigned NumElts) const;
+
/// Return the unique reference to a vector type of the specified
/// element type and size.
///
@@ -1384,6 +1330,20 @@ public:
Expr *SizeExpr,
SourceLocation AttrLoc) const;
+ /// Return the unique reference to the matrix type of the specified element
+ /// type and size
+ ///
+ /// \pre \p ElementType must be a valid matrix element type (see
+ /// MatrixType::isValidElementType).
+ QualType getConstantMatrixType(QualType ElementType, unsigned NumRows,
+ unsigned NumColumns) const;
+
+ /// Return the unique reference to the matrix type of the specified element
+ /// type and size
+ QualType getDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
+ Expr *ColumnExpr,
+ SourceLocation AttrLoc) const;
+
QualType getDependentAddressSpaceType(QualType PointeeType,
Expr *AddrSpaceExpr,
SourceLocation AttrLoc) const;
@@ -1517,6 +1477,8 @@ public:
QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
ArrayRef<ObjCProtocolDecl *> protocols) const;
+ void adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig,
+ ObjCTypeParamDecl *New) const;
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
@@ -1542,7 +1504,9 @@ public:
/// C++11 deduced auto type.
QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
- bool IsDependent, bool IsPack = false) const;
+ bool IsDependent, bool IsPack = false,
+ ConceptDecl *TypeConstraintConcept = nullptr,
+ ArrayRef<TemplateArgument> TypeConstraintArgs ={}) const;
/// C++11 deduction pattern for 'auto' type.
QualType getAutoDeductType() const;
@@ -1710,23 +1674,9 @@ public:
return NSCopyingName;
}
- CanQualType getNSUIntegerType() const {
- assert(Target && "Expected target to be initialized");
- const llvm::Triple &T = Target->getTriple();
- // Windows is LLP64 rather than LP64
- if (T.isOSWindows() && T.isArch64Bit())
- return UnsignedLongLongTy;
- return UnsignedLongTy;
- }
+ CanQualType getNSUIntegerType() const;
- CanQualType getNSIntegerType() const {
- assert(Target && "Expected target to be initialized");
- const llvm::Triple &T = Target->getTriple();
- // Windows is LLP64 rather than LP64
- if (T.isOSWindows() && T.isArch64Bit())
- return LongLongTy;
- return LongTy;
- }
+ CanQualType getNSIntegerType() const;
/// Retrieve the identifier 'bool'.
IdentifierInfo *getBoolName() const {
@@ -1941,6 +1891,15 @@ public:
return getTypeDeclType(getBuiltinMSVaListDecl());
}
+ /// Retrieve the implicitly-predeclared 'struct _GUID' declaration.
+ TagDecl *getMSGuidTagDecl() const { return MSGuidTagDecl; }
+
+ /// Retrieve the implicitly-predeclared 'struct _GUID' type.
+ QualType getMSGuidType() const {
+ assert(MSGuidTagDecl && "asked for GUID type but MS extensions disabled");
+ return getTagDeclType(MSGuidTagDecl);
+ }
+
/// Return whether a declaration to a builtin is allowed to be
/// overloaded/redeclared.
bool canBuiltinBeRedeclared(const FunctionDecl *) const;
@@ -2204,9 +2163,7 @@ public:
/// Return the alignment (in bytes) of the thrown exception object. This is
/// only meaningful for targets that allocate C++ exceptions in a system
/// runtime, such as those using the Itanium C++ ABI.
- CharUnits getExnObjectAlignment() const {
- return toCharUnitsFromBits(Target->getExnObjectAlignment());
- }
+ CharUnits getExnObjectAlignment() const;
/// Get or compute information about the layout of the specified
/// record (struct/union/class) \p D, which indicates its size and field
@@ -2624,7 +2581,7 @@ public:
QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
bool Unqualified = false, bool BlockReturnType = false);
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false);
+ bool Unqualified = false, bool AllowCXX = false);
QualType mergeFunctionParameterTypes(QualType, QualType,
bool OfBlockPointer = false,
bool Unqualified = false);
@@ -2845,6 +2802,10 @@ public:
/// PredefinedExpr to cache evaluated results.
StringLiteral *getPredefinedStringLiteralFromCache(StringRef Key) const;
+ /// Return a declaration for the global GUID object representing the given
+ /// GUID value.
+ MSGuidDecl *getMSGuidDecl(MSGuidDeclParts Parts) const;
+
/// Parses the target attributes passed in, and returns only the ones that are
/// valid feature names.
ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const;
@@ -3023,8 +2984,6 @@ private:
llvm::PointerIntPair<StoredDeclsMap *, 1> LastSDM;
std::vector<Decl *> TraversalScope;
- class ParentMap;
- std::map<ast_type_traits::TraversalKind, std::unique_ptr<ParentMap>> Parents;
std::unique_ptr<VTableContextBase> VTContext;
@@ -3037,6 +2996,7 @@ public:
PSF_Write = 0x2,
PSF_Execute = 0x4,
PSF_Implicit = 0x8,
+ PSF_ZeroInit = 0x10,
PSF_Invalid = 0x80000000U,
};
@@ -3054,8 +3014,20 @@ public:
};
llvm::StringMap<SectionInfo> SectionInfos;
+
+ /// Return a new OMPTraitInfo object owned by this context.
+ OMPTraitInfo &getNewOMPTraitInfo();
+
+private:
+ /// All OMPTraitInfo objects live in this collection, one per
+ /// `pragma omp [begin] declare variant` directive.
+ SmallVector<std::unique_ptr<OMPTraitInfo>, 4> OMPTraitInfoVector;
};
+/// Insertion operator for diagnostics.
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const ASTContext::SectionInfo &Section);
+
/// Utility function for constructing a nullary selector.
inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
@@ -3068,22 +3040,6 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
return Ctx.Selectors.getSelector(1, &II);
}
-class TraversalKindScope {
- ASTContext &Ctx;
- ast_type_traits::TraversalKind TK = ast_type_traits::TK_AsIs;
-
-public:
- TraversalKindScope(ASTContext &Ctx,
- llvm::Optional<ast_type_traits::TraversalKind> ScopeTK)
- : Ctx(Ctx) {
- TK = Ctx.getTraversalKind();
- if (ScopeTK)
- Ctx.setTraversalKind(*ScopeTK);
- }
-
- ~TraversalKindScope() { Ctx.setTraversalKind(TK); }
-};
-
} // namespace clang
// operator new and delete aren't allowed inside namespaces.
diff --git a/clang/include/clang/AST/ASTDumper.h b/clang/include/clang/AST/ASTDumper.h
index 61202f057a80..a154bc2db3a7 100644
--- a/clang/include/clang/AST/ASTDumper.h
+++ b/clang/include/clang/AST/ASTDumper.h
@@ -11,6 +11,7 @@
#include "clang/AST/ASTNodeTraverser.h"
#include "clang/AST/TextNodeDumper.h"
+#include "clang/Basic/SourceManager.h"
namespace clang {
@@ -23,18 +24,11 @@ class ASTDumper : public ASTNodeTraverser<ASTDumper, TextNodeDumper> {
const bool ShowColors;
public:
- ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits,
- const SourceManager *SM)
- : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {}
-
- ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits,
- const SourceManager *SM, bool ShowColors)
- : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {}
- ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits,
- const SourceManager *SM, bool ShowColors,
- const PrintingPolicy &PrintPolicy)
- : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
- ShowColors(ShowColors) {}
+ ASTDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors)
+ : NodeDumper(OS, Context, ShowColors), OS(OS), ShowColors(ShowColors) {}
+
+ ASTDumper(raw_ostream &OS, bool ShowColors)
+ : NodeDumper(OS, ShowColors), OS(OS), ShowColors(ShowColors) {}
TextNodeDumper &doGetNodeDelegate() { return NodeDumper; }
diff --git a/clang/include/clang/AST/ASTDumperUtils.h b/clang/include/clang/AST/ASTDumperUtils.h
index 55a085449a9b..1dce913049ad 100644
--- a/clang/include/clang/AST/ASTDumperUtils.h
+++ b/clang/include/clang/AST/ASTDumperUtils.h
@@ -62,6 +62,8 @@ static const TerminalColor LocationColor = {llvm::raw_ostream::YELLOW, false};
static const TerminalColor ValueKindColor = {llvm::raw_ostream::CYAN, false};
// bitfield/objcproperty/objcsubscript/vectorcomponent
static const TerminalColor ObjectKindColor = {llvm::raw_ostream::CYAN, false};
+// contains-errors
+static const TerminalColor ErrorsColor = {llvm::raw_ostream::RED, true};
// Null statements
static const TerminalColor NullColor = {llvm::raw_ostream::BLUE, false};
diff --git a/clang/include/clang/AST/ASTFwd.h b/clang/include/clang/AST/ASTFwd.h
index 5a891817b336..65319a19728b 100644
--- a/clang/include/clang/AST/ASTFwd.h
+++ b/clang/include/clang/AST/ASTFwd.h
@@ -27,8 +27,8 @@ class Type;
#include "clang/AST/TypeNodes.inc"
class CXXCtorInitializer;
class OMPClause;
-#define OPENMP_CLAUSE(KIND, CLASSNAME) class CLASSNAME;
-#include "clang/Basic/OpenMPKinds.def"
+#define OMP_CLAUSE_CLASS(Enum, Str, Class) class Class;
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
} // end namespace clang
diff --git a/clang/include/clang/AST/ASTImporter.h b/clang/include/clang/AST/ASTImporter.h
index 490b34bf95e8..205d7ec67754 100644
--- a/clang/include/clang/AST/ASTImporter.h
+++ b/clang/include/clang/AST/ASTImporter.h
@@ -16,6 +16,7 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
@@ -349,6 +350,10 @@ class TypeSourceInfo;
return ToOrErr.takeError();
}
+ /// Import cleanup objects owned by ExprWithCleanup.
+ llvm::Expected<ExprWithCleanups::CleanupObject>
+ Import(ExprWithCleanups::CleanupObject From);
+
/// Import the given type from the "from" context into the "to"
/// context. A null type is imported as a null type (no error).
///
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index e0ebb020e697..26656b7162b6 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -15,16 +15,20 @@
#ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H
#define LLVM_CLANG_AST_ASTNODETRAVERSER_H
+#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/AttrVisitor.h"
#include "clang/AST/CommentVisitor.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/LocInfoType.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TemplateArgumentVisitor.h"
+#include "clang/AST/Type.h"
#include "clang/AST/TypeVisitor.h"
namespace clang {
+class APValue;
+
/**
ASTNodeTraverser traverses the Clang AST for dumping purposes.
@@ -49,6 +53,7 @@ struct {
void Visit(const OMPClause *C);
void Visit(const BlockDecl::Capture &C);
void Visit(const GenericSelectionExpr::ConstAssociation &A);
+ void Visit(const APValue &Value, QualType Ty);
};
*/
template <typename Derived, typename NodeDelegateType>
@@ -65,8 +70,7 @@ class ASTNodeTraverser
/// not already been loaded.
bool Deserialize = false;
- ast_type_traits::TraversalKind Traversal =
- ast_type_traits::TraversalKind::TK_AsIs;
+ TraversalKind Traversal = TraversalKind::TK_AsIs;
NodeDelegateType &getNodeDelegate() {
return getDerived().doGetNodeDelegate();
@@ -77,7 +81,7 @@ public:
void setDeserialize(bool D) { Deserialize = D; }
bool getDeserialize() const { return Deserialize; }
- void SetTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; }
+ void SetTraversalKind(TraversalKind TK) { Traversal = TK; }
void Visit(const Decl *D) {
getNodeDelegate().AddChild([=] {
@@ -108,12 +112,12 @@ public:
if (auto *E = dyn_cast_or_null<Expr>(S)) {
switch (Traversal) {
- case ast_type_traits::TK_AsIs:
+ case TK_AsIs:
break;
- case ast_type_traits::TK_IgnoreImplicitCastsAndParentheses:
+ case TK_IgnoreImplicitCastsAndParentheses:
S = E->IgnoreParenImpCasts();
break;
- case ast_type_traits::TK_IgnoreUnlessSpelledInSource:
+ case TK_IgnoreUnlessSpelledInSource:
S = E->IgnoreUnlessSpelledInSource();
break;
}
@@ -131,8 +135,7 @@ public:
if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S))
return;
- if (isa<LambdaExpr>(S) &&
- Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource)
+ if (isa<LambdaExpr>(S) && Traversal == TK_IgnoreUnlessSpelledInSource)
return;
for (const Stmt *SubStmt : S->children())
@@ -212,6 +215,10 @@ public:
});
}
+ void Visit(const APValue &Value, QualType Ty) {
+ getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); });
+ }
+
void Visit(const comments::Comment *C, const comments::FullComment *FC) {
getNodeDelegate().AddChild([=] {
getNodeDelegate().Visit(C, FC);
@@ -228,7 +235,7 @@ public:
});
}
- void Visit(const ast_type_traits::DynTypedNode &N) {
+ void Visit(const DynTypedNode &N) {
// FIXME: Improve this with a switch or a visitor pattern.
if (const auto *D = N.get<Decl>())
Visit(D);
@@ -353,8 +360,6 @@ public:
void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
for (const auto &Arg : *T)
Visit(Arg);
- if (T->isTypeAlias())
- Visit(T->getAliasedType());
}
void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
Visit(T->getPointeeType());
@@ -548,8 +553,8 @@ public:
}
void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
- if (const auto *TC = D->getPlaceholderTypeConstraint())
- Visit(TC->getImmediatelyDeclaredConstraint());
+ if (const auto *E = D->getPlaceholderTypeConstraint())
+ Visit(E);
if (D->hasDefaultArgument())
Visit(D->getDefaultArgument(), SourceRange(),
D->getDefaultArgStorage().getInheritedFrom(),
@@ -658,7 +663,7 @@ public:
}
void VisitLambdaExpr(const LambdaExpr *Node) {
- if (Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource) {
+ if (Traversal == TK_IgnoreUnlessSpelledInSource) {
for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) {
const auto *C = Node->capture_begin() + I;
if (!C->isExplicit())
@@ -683,6 +688,15 @@ public:
Visit(A);
}
+ void VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) {
+ Visit(E->getParameter());
+ }
+ void VisitSubstNonTypeTemplateParmPackExpr(
+ const SubstNonTypeTemplateParmPackExpr *E) {
+ Visit(E->getParameterPack());
+ Visit(E->getArgumentPack());
+ }
+
void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
if (const VarDecl *CatchParam = Node->getCatchParamDecl())
Visit(CatchParam);
@@ -691,6 +705,11 @@ public:
void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
Visit(TA.getAsExpr());
}
+
+ void VisitTypeTemplateArgument(const TemplateArgument &TA) {
+ Visit(TA.getAsType());
+ }
+
void VisitPackTemplateArgument(const TemplateArgument &TA) {
for (const auto &TArg : TA.pack_elements())
Visit(TArg);
diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h
index 1a12281d039d..328b7bce6ba5 100644
--- a/clang/include/clang/AST/ASTTypeTraits.h
+++ b/clang/include/clang/AST/ASTTypeTraits.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_AST_ASTTYPETRAITS_H
#include "clang/AST/ASTFwd.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TypeLoc.h"
@@ -33,8 +34,6 @@ namespace clang {
struct PrintingPolicy;
-namespace ast_type_traits {
-
/// Defines how we descend a level in the AST when we pass
/// through expressions.
enum TraversalKind {
@@ -138,6 +137,7 @@ private:
NKI_QualType,
NKI_TypeLoc,
NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
+ NKI_CXXBaseSpecifier,
NKI_CXXCtorInitializer,
NKI_NestedNameSpecifier,
NKI_Decl,
@@ -150,8 +150,8 @@ private:
#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
#include "clang/AST/TypeNodes.inc"
NKI_OMPClause,
-#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class,
-#include "clang/Basic/OpenMPKinds.def"
+#define OMP_CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
NKI_NumberOfKinds
};
@@ -200,14 +200,15 @@ KIND_TO_KIND_ID(Decl)
KIND_TO_KIND_ID(Stmt)
KIND_TO_KIND_ID(Type)
KIND_TO_KIND_ID(OMPClause)
+KIND_TO_KIND_ID(CXXBaseSpecifier)
#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
#include "clang/AST/DeclNodes.inc"
#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
#include "clang/AST/StmtNodes.inc"
#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
#include "clang/AST/TypeNodes.inc"
-#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class)
-#include "clang/Basic/OpenMPKinds.def"
+#define OMP_CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
#undef KIND_TO_KIND_ID
inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
@@ -277,7 +278,7 @@ public:
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
/// Dumps the node to the given output stream.
- void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
+ void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
/// For nodes which represent textual entities in the source code,
/// return their SourceRange. For all other nodes, return SourceRange().
@@ -465,22 +466,22 @@ private:
template <typename T>
struct DynTypedNode::BaseConverter<
- T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
+ T, std::enable_if_t<std::is_base_of<Decl, T>::value>>
: public DynCastPtrConverter<T, Decl> {};
template <typename T>
struct DynTypedNode::BaseConverter<
- T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
+ T, std::enable_if_t<std::is_base_of<Stmt, T>::value>>
: public DynCastPtrConverter<T, Stmt> {};
template <typename T>
struct DynTypedNode::BaseConverter<
- T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
+ T, std::enable_if_t<std::is_base_of<Type, T>::value>>
: public DynCastPtrConverter<T, Type> {};
template <typename T>
struct DynTypedNode::BaseConverter<
- T, typename std::enable_if<std::is_base_of<OMPClause, T>::value>::type>
+ T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
: public DynCastPtrConverter<T, OMPClause> {};
template <>
@@ -512,6 +513,10 @@ template <>
struct DynTypedNode::BaseConverter<
TypeLoc, void> : public ValueConverter<TypeLoc> {};
+template <>
+struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
+ : public PtrConverter<CXXBaseSpecifier> {};
+
// The only operation we allow on unsupported types is \c get.
// This allows to conveniently use \c DynTypedNode when having an arbitrary
// AST node that is not supported, but prevents misuse - a user cannot create
@@ -522,18 +527,29 @@ template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
}
};
-} // end namespace ast_type_traits
+// Previously these types were defined in the clang::ast_type_traits namespace.
+// Provide typedefs so that legacy code can be fixed asynchronously.
+namespace ast_type_traits {
+using DynTypedNode = ::clang::DynTypedNode;
+using ASTNodeKind = ::clang::ASTNodeKind;
+using TraversalKind = ::clang::TraversalKind;
+
+constexpr TraversalKind TK_AsIs = ::clang::TK_AsIs;
+constexpr TraversalKind TK_IgnoreImplicitCastsAndParentheses =
+ ::clang::TK_IgnoreImplicitCastsAndParentheses;
+constexpr TraversalKind TK_IgnoreUnlessSpelledInSource =
+ ::clang::TK_IgnoreUnlessSpelledInSource;
+} // namespace ast_type_traits
+
} // end namespace clang
namespace llvm {
template <>
-struct DenseMapInfo<clang::ast_type_traits::ASTNodeKind>
- : clang::ast_type_traits::ASTNodeKind::DenseMapInfo {};
+struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {};
template <>
-struct DenseMapInfo<clang::ast_type_traits::DynTypedNode>
- : clang::ast_type_traits::DynTypedNode::DenseMapInfo {};
+struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {};
} // end namespace llvm
diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h
index bbaa46363d97..1b457337d658 100644
--- a/clang/include/clang/AST/Attr.h
+++ b/clang/include/clang/AST/Attr.h
@@ -13,13 +13,13 @@
#ifndef LLVM_CLANG_AST_ATTR_H
#define LLVM_CLANG_AST_ATTR_H
-#include "clang/AST/ASTContextAllocate.h" // For Attrs.inc
+#include "clang/AST/ASTFwd.h"
#include "clang/AST/AttrIterator.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/AttributeCommonInfo.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/Sanitizers.h"
@@ -40,6 +40,7 @@ class Expr;
class QualType;
class FunctionDecl;
class TypeSourceInfo;
+class OMPTraitInfo;
/// Attr - This represents one attribute.
class Attr : public AttributeCommonInfo {
diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def
index 74a45ee4ccc0..039765dfdfea 100644
--- a/clang/include/clang/AST/BuiltinTypes.def
+++ b/clang/include/clang/AST/BuiltinTypes.def
@@ -212,6 +212,9 @@ FLOATING_TYPE(LongDouble, LongDoubleTy)
// '_Float16'
FLOATING_TYPE(Float16, HalfTy)
+// '__bf16'
+FLOATING_TYPE(BFloat16, BFloat16Ty)
+
// '__float128'
FLOATING_TYPE(Float128, Float128Ty)
@@ -310,11 +313,20 @@ PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy)
// context.
PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
+// A placeholder type for incomplete matrix index expressions.
+PLACEHOLDER_TYPE(IncompleteMatrixIdx, IncompleteMatrixIdxTy)
+
// A placeholder type for OpenMP array sections.
PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy)
+// A placeholder type for OpenMP array shaping operation.
+PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy)
+
+// A placeholder type for OpenMP iterators.
+PLACEHOLDER_TYPE(OMPIterator, OMPIteratorTy)
+
#ifdef LAST_BUILTIN_TYPE
-LAST_BUILTIN_TYPE(OMPArraySection)
+LAST_BUILTIN_TYPE(OMPIterator)
#undef LAST_BUILTIN_TYPE
#endif
diff --git a/clang/include/clang/AST/CXXInheritance.h b/clang/include/clang/AST/CXXInheritance.h
index f223c1f2f4f0..8b1bcb367b3b 100644
--- a/clang/include/clang/AST/CXXInheritance.h
+++ b/clang/include/clang/AST/CXXInheritance.h
@@ -119,7 +119,7 @@ class CXXBasePaths {
friend class CXXRecordDecl;
/// The type from which this search originated.
- CXXRecordDecl *Origin = nullptr;
+ const CXXRecordDecl *Origin = nullptr;
/// Paths - The actual set of paths that can be taken from the
/// derived class to the same base class.
@@ -225,8 +225,8 @@ public:
/// Retrieve the type from which this base-paths search
/// began
- CXXRecordDecl *getOrigin() const { return Origin; }
- void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; }
+ const CXXRecordDecl *getOrigin() const { return Origin; }
+ void setOrigin(const CXXRecordDecl *Rec) { Origin = Rec; }
/// Clear the base-paths results.
void clear();
diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
index bd4d8247aeca..33e65f8ebf44 100644
--- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
+++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
@@ -140,6 +140,7 @@ FIELD(HasInheritedAssignment, 1, NO_MERGE)
/// @{
FIELD(NeedOverloadResolutionForCopyConstructor, 1, NO_MERGE)
FIELD(NeedOverloadResolutionForMoveConstructor, 1, NO_MERGE)
+FIELD(NeedOverloadResolutionForCopyAssignment, 1, NO_MERGE)
FIELD(NeedOverloadResolutionForMoveAssignment, 1, NO_MERGE)
FIELD(NeedOverloadResolutionForDestructor, 1, NO_MERGE)
/// @}
@@ -149,6 +150,7 @@ FIELD(NeedOverloadResolutionForDestructor, 1, NO_MERGE)
/// @{
FIELD(DefaultedCopyConstructorIsDeleted, 1, NO_MERGE)
FIELD(DefaultedMoveConstructorIsDeleted, 1, NO_MERGE)
+FIELD(DefaultedCopyAssignmentIsDeleted, 1, NO_MERGE)
FIELD(DefaultedMoveAssignmentIsDeleted, 1, NO_MERGE)
FIELD(DefaultedDestructorIsDeleted, 1, NO_MERGE)
/// @}
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index 2e00d344533d..488284713bce 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -74,7 +74,7 @@ public:
/// canonical type pointers.
template <typename U>
CanQual(const CanQual<U> &Other,
- typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0);
+ std::enable_if_t<std::is_base_of<T, U>::value, int> = 0);
/// Retrieve the underlying type pointer, which refers to a
/// canonical type.
@@ -264,6 +264,8 @@ public:
// Type predicates
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessBuiltinType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
@@ -384,7 +386,7 @@ struct PointerLikeTypeTraits<clang::CanQual<T>> {
}
// qualifier information is encoded in the low bits.
- enum { NumLowBitsAvailable = 0 };
+ static constexpr int NumLowBitsAvailable = 0;
};
} // namespace llvm
diff --git a/clang/include/clang/AST/Comment.h b/clang/include/clang/AST/Comment.h
index cd9c1ce2bce0..54a4b0a9cfe6 100644
--- a/clang/include/clang/AST/Comment.h
+++ b/clang/include/clang/AST/Comment.h
@@ -209,9 +209,7 @@ public:
void dump() const;
void dumpColor() const;
- void dump(const ASTContext &Context) const;
- void dump(raw_ostream &OS, const CommandTraits *Traits,
- const SourceManager *SM) const;
+ void dump(raw_ostream &OS, const ASTContext &Context) const;
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
diff --git a/clang/include/clang/AST/CommentCommands.td b/clang/include/clang/AST/CommentCommands.td
index d387df7ce570..fbbfc9f7e0b7 100644
--- a/clang/include/clang/AST/CommentCommands.td
+++ b/clang/include/clang/AST/CommentCommands.td
@@ -87,6 +87,7 @@ def P : InlineCommand<"p">;
def A : InlineCommand<"a">;
def E : InlineCommand<"e">;
def Em : InlineCommand<"em">;
+def Ref : InlineCommand<"ref">;
def Anchor : InlineCommand<"anchor">;
//===----------------------------------------------------------------------===//
@@ -205,7 +206,6 @@ def Paragraph : VerbatimLineCommand<"paragraph">;
def Mainpage : VerbatimLineCommand<"mainpage">;
def Subpage : VerbatimLineCommand<"subpage">;
-def Ref : VerbatimLineCommand<"ref">;
def Relates : VerbatimLineCommand<"relates">;
def Related : VerbatimLineCommand<"related">;
diff --git a/clang/include/clang/AST/CommentSema.h b/clang/include/clang/AST/CommentSema.h
index 307618fa5363..6dfe0f4920d0 100644
--- a/clang/include/clang/AST/CommentSema.h
+++ b/clang/include/clang/AST/CommentSema.h
@@ -217,6 +217,9 @@ public:
bool isTemplateOrSpecialization();
bool isRecordLikeDecl();
bool isClassOrStructDecl();
+ /// \return \c true if the declaration that this comment is attached to
+ /// declares either struct, class or tag typedef.
+ bool isClassOrStructOrTagTypedefDecl();
bool isUnionDecl();
bool isObjCInterfaceDecl();
bool isObjCProtocolDecl();
diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h
new file mode 100644
index 000000000000..ac2daf9eb95a
--- /dev/null
+++ b/clang/include/clang/AST/ComputeDependence.h
@@ -0,0 +1,194 @@
+//===--- ComputeDependence.h -------------------------------------- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Calculate various template dependency flags for the AST.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H
+#define LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H
+
+#include "clang/AST/DependenceFlags.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
+#include "llvm/ADT/ArrayRef.h"
+
+namespace clang {
+
+class ASTContext;
+
+class Expr;
+class FullExpr;
+class OpaqueValueExpr;
+class ParenExpr;
+class UnaryOperator;
+class UnaryExprOrTypeTraitExpr;
+class ArraySubscriptExpr;
+class MatrixSubscriptExpr;
+class CompoundLiteralExpr;
+class CastExpr;
+class BinaryOperator;
+class ConditionalOperator;
+class BinaryConditionalOperator;
+class StmtExpr;
+class ConvertVectorExpr;
+class VAArgExpr;
+class ChooseExpr;
+class NoInitExpr;
+class ArrayInitLoopExpr;
+class ImplicitValueInitExpr;
+class InitListExpr;
+class ExtVectorElementExpr;
+class BlockExpr;
+class AsTypeExpr;
+class DeclRefExpr;
+class RecoveryExpr;
+class CXXRewrittenBinaryOperator;
+class CXXStdInitializerListExpr;
+class CXXTypeidExpr;
+class MSPropertyRefExpr;
+class MSPropertySubscriptExpr;
+class CXXUuidofExpr;
+class CXXThisExpr;
+class CXXThrowExpr;
+class CXXBindTemporaryExpr;
+class CXXScalarValueInitExpr;
+class CXXDeleteExpr;
+class ArrayTypeTraitExpr;
+class ExpressionTraitExpr;
+class CXXNoexceptExpr;
+class PackExpansionExpr;
+class SubstNonTypeTemplateParmExpr;
+class CoroutineSuspendExpr;
+class DependentCoawaitExpr;
+class CXXNewExpr;
+class CXXPseudoDestructorExpr;
+class OverloadExpr;
+class DependentScopeDeclRefExpr;
+class CXXConstructExpr;
+class LambdaExpr;
+class CXXUnresolvedConstructExpr;
+class CXXDependentScopeMemberExpr;
+class MaterializeTemporaryExpr;
+class CXXFoldExpr;
+class TypeTraitExpr;
+class ConceptSpecializationExpr;
+class PredefinedExpr;
+class CallExpr;
+class OffsetOfExpr;
+class MemberExpr;
+class ShuffleVectorExpr;
+class GenericSelectionExpr;
+class DesignatedInitExpr;
+class ParenListExpr;
+class PseudoObjectExpr;
+class AtomicExpr;
+class OMPArraySectionExpr;
+class OMPArrayShapingExpr;
+class OMPIteratorExpr;
+class ObjCArrayLiteral;
+class ObjCDictionaryLiteral;
+class ObjCBoxedExpr;
+class ObjCEncodeExpr;
+class ObjCIvarRefExpr;
+class ObjCPropertyRefExpr;
+class ObjCSubscriptRefExpr;
+class ObjCIsaExpr;
+class ObjCIndirectCopyRestoreExpr;
+class ObjCMessageExpr;
+
+// The following functions are called from constructors of `Expr`, so they
+// should not access anything beyond basic
+ExprDependence computeDependence(FullExpr *E);
+ExprDependence computeDependence(OpaqueValueExpr *E);
+ExprDependence computeDependence(ParenExpr *E);
+ExprDependence computeDependence(UnaryOperator *E);
+ExprDependence computeDependence(UnaryExprOrTypeTraitExpr *E);
+ExprDependence computeDependence(ArraySubscriptExpr *E);
+ExprDependence computeDependence(MatrixSubscriptExpr *E);
+ExprDependence computeDependence(CompoundLiteralExpr *E);
+ExprDependence computeDependence(CastExpr *E);
+ExprDependence computeDependence(BinaryOperator *E);
+ExprDependence computeDependence(ConditionalOperator *E);
+ExprDependence computeDependence(BinaryConditionalOperator *E);
+ExprDependence computeDependence(StmtExpr *E, unsigned TemplateDepth);
+ExprDependence computeDependence(ConvertVectorExpr *E);
+ExprDependence computeDependence(VAArgExpr *E);
+ExprDependence computeDependence(ChooseExpr *E);
+ExprDependence computeDependence(NoInitExpr *E);
+ExprDependence computeDependence(ArrayInitLoopExpr *E);
+ExprDependence computeDependence(ImplicitValueInitExpr *E);
+ExprDependence computeDependence(InitListExpr *E);
+ExprDependence computeDependence(ExtVectorElementExpr *E);
+ExprDependence computeDependence(BlockExpr *E);
+ExprDependence computeDependence(AsTypeExpr *E);
+ExprDependence computeDependence(DeclRefExpr *E, const ASTContext &Ctx);
+ExprDependence computeDependence(RecoveryExpr *E);
+ExprDependence computeDependence(CXXRewrittenBinaryOperator *E);
+ExprDependence computeDependence(CXXStdInitializerListExpr *E);
+ExprDependence computeDependence(CXXTypeidExpr *E);
+ExprDependence computeDependence(MSPropertyRefExpr *E);
+ExprDependence computeDependence(MSPropertySubscriptExpr *E);
+ExprDependence computeDependence(CXXUuidofExpr *E);
+ExprDependence computeDependence(CXXThisExpr *E);
+ExprDependence computeDependence(CXXThrowExpr *E);
+ExprDependence computeDependence(CXXBindTemporaryExpr *E);
+ExprDependence computeDependence(CXXScalarValueInitExpr *E);
+ExprDependence computeDependence(CXXDeleteExpr *E);
+ExprDependence computeDependence(ArrayTypeTraitExpr *E);
+ExprDependence computeDependence(ExpressionTraitExpr *E);
+ExprDependence computeDependence(CXXNoexceptExpr *E, CanThrowResult CT);
+ExprDependence computeDependence(PackExpansionExpr *E);
+ExprDependence computeDependence(SubstNonTypeTemplateParmExpr *E);
+ExprDependence computeDependence(CoroutineSuspendExpr *E);
+ExprDependence computeDependence(DependentCoawaitExpr *E);
+ExprDependence computeDependence(CXXNewExpr *E);
+ExprDependence computeDependence(CXXPseudoDestructorExpr *E);
+ExprDependence computeDependence(OverloadExpr *E, bool KnownDependent,
+ bool KnownInstantiationDependent,
+ bool KnownContainsUnexpandedParameterPack);
+ExprDependence computeDependence(DependentScopeDeclRefExpr *E);
+ExprDependence computeDependence(CXXConstructExpr *E);
+ExprDependence computeDependence(LambdaExpr *E,
+ bool ContainsUnexpandedParameterPack);
+ExprDependence computeDependence(CXXUnresolvedConstructExpr *E);
+ExprDependence computeDependence(CXXDependentScopeMemberExpr *E);
+ExprDependence computeDependence(MaterializeTemporaryExpr *E);
+ExprDependence computeDependence(CXXFoldExpr *E);
+ExprDependence computeDependence(TypeTraitExpr *E);
+ExprDependence computeDependence(ConceptSpecializationExpr *E,
+ bool ValueDependent);
+
+ExprDependence computeDependence(PredefinedExpr *E);
+ExprDependence computeDependence(CallExpr *E, llvm::ArrayRef<Expr *> PreArgs);
+ExprDependence computeDependence(OffsetOfExpr *E);
+ExprDependence computeDependence(MemberExpr *E);
+ExprDependence computeDependence(ShuffleVectorExpr *E);
+ExprDependence computeDependence(GenericSelectionExpr *E,
+ bool ContainsUnexpandedPack);
+ExprDependence computeDependence(DesignatedInitExpr *E);
+ExprDependence computeDependence(ParenListExpr *E);
+ExprDependence computeDependence(PseudoObjectExpr *E);
+ExprDependence computeDependence(AtomicExpr *E);
+
+ExprDependence computeDependence(OMPArraySectionExpr *E);
+ExprDependence computeDependence(OMPArrayShapingExpr *E);
+ExprDependence computeDependence(OMPIteratorExpr *E);
+
+ExprDependence computeDependence(ObjCArrayLiteral *E);
+ExprDependence computeDependence(ObjCDictionaryLiteral *E);
+ExprDependence computeDependence(ObjCBoxedExpr *E);
+ExprDependence computeDependence(ObjCEncodeExpr *E);
+ExprDependence computeDependence(ObjCIvarRefExpr *E);
+ExprDependence computeDependence(ObjCPropertyRefExpr *E);
+ExprDependence computeDependence(ObjCSubscriptRefExpr *E);
+ExprDependence computeDependence(ObjCIsaExpr *E);
+ExprDependence computeDependence(ObjCIndirectCopyRestoreExpr *E);
+ExprDependence computeDependence(ObjCMessageExpr *E);
+
+} // namespace clang
+#endif
diff --git a/clang/include/clang/AST/DataCollection.h b/clang/include/clang/AST/DataCollection.h
index 37f101793ecc..14d1bc188623 100644
--- a/clang/include/clang/AST/DataCollection.h
+++ b/clang/include/clang/AST/DataCollection.h
@@ -50,10 +50,9 @@ template <class T> void addDataToConsumer(T &DataConsumer, const QualType &QT) {
}
template <class T, class Type>
-typename std::enable_if<
- std::is_integral<Type>::value || std::is_enum<Type>::value ||
- std::is_convertible<Type, size_t>::value // for llvm::hash_code
- >::type
+std::enable_if_t<std::is_integral<Type>::value || std::is_enum<Type>::value ||
+ std::is_convertible<Type, size_t>::value // for llvm::hash_code
+ >
addDataToConsumer(T &DataConsumer, Type Data) {
DataConsumer.update(StringRef(reinterpret_cast<char *>(&Data), sizeof(Data)));
}
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 43c6c7b85db4..28faa2c1fc78 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -2030,7 +2030,7 @@ public:
/// declaration to the declaration that is a definition (if there is one).
bool isDefined(const FunctionDecl *&Definition) const;
- virtual bool isDefined() const {
+ bool isDefined() const {
const FunctionDecl* Definition;
return isDefined(Definition);
}
@@ -2125,19 +2125,17 @@ public:
bool isTrivialForCall() const { return FunctionDeclBits.IsTrivialForCall; }
void setTrivialForCall(bool IT) { FunctionDeclBits.IsTrivialForCall = IT; }
- /// Whether this function is defaulted per C++0x. Only valid for
- /// special member functions.
+ /// Whether this function is defaulted. Valid for e.g.
+ /// special member functions, defaulted comparisions (not methods!).
bool isDefaulted() const { return FunctionDeclBits.IsDefaulted; }
void setDefaulted(bool D = true) { FunctionDeclBits.IsDefaulted = D; }
- /// Whether this function is explicitly defaulted per C++0x. Only valid
- /// for special member functions.
+ /// Whether this function is explicitly defaulted.
bool isExplicitlyDefaulted() const {
return FunctionDeclBits.IsExplicitlyDefaulted;
}
- /// State that this function is explicitly defaulted per C++0x. Only valid
- /// for special member functions.
+ /// State that this function is explicitly defaulted.
void setExplicitlyDefaulted(bool ED = true) {
FunctionDeclBits.IsExplicitlyDefaulted = ED;
}
@@ -2306,8 +2304,13 @@ public:
/// allocation function. [...]
///
/// If this function is an aligned allocation/deallocation function, return
- /// true through IsAligned.
- bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const;
+ /// the parameter number of the requested alignment through AlignmentParam.
+ ///
+ /// If this function is an allocation/deallocation function that takes
+ /// the `std::nothrow_t` tag, return true through IsNothrow,
+ bool isReplaceableGlobalAllocationFunction(
+ Optional<unsigned> *AlignmentParam = nullptr,
+ bool *IsNothrow = nullptr) const;
/// Determine if this function provides an inline implementation of a builtin.
bool isInlineBuiltinDeclaration() const;
@@ -2436,6 +2439,14 @@ public:
/// parameters have default arguments (in C++).
unsigned getMinRequiredArguments() const;
+ /// Determine whether this function has a single parameter, or multiple
+ /// parameters where all but the first have default arguments.
+ ///
+ /// This notion is used in the definition of copy/move constructors and
+ /// initializer list constructors. Note that, unlike getMinRequiredArguments,
+ /// parameter packs are not treated specially here.
+ bool hasOneParamOrDefaultArgs() const;
+
/// Find the source location information for how the type of this function
/// was written. May be absent (for example if the function was declared via
/// a typedef) and may contain a different type from that of the function
@@ -2607,7 +2618,13 @@ public:
/// Retrieve the function declaration from which this function could
/// be instantiated, if it is an instantiation (rather than a non-template
/// or a specialization, for example).
- FunctionDecl *getTemplateInstantiationPattern() const;
+ ///
+ /// If \p ForDefinition is \c false, explicit specializations will be treated
+ /// as if they were implicit instantiations. This will then find the pattern
+ /// corresponding to non-definition portions of the declaration, such as
+ /// default arguments and the exception specification.
+ FunctionDecl *
+ getTemplateInstantiationPattern(bool ForDefinition = true) const;
/// Retrieve the primary template that this function template
/// specialization either specializes or was instantiated from.
@@ -2915,12 +2932,15 @@ public:
/// Returns the parent of this field declaration, which
/// is the struct in which this field is defined.
+ ///
+ /// Returns null if this is not a normal class/struct field declaration, e.g.
+ /// ObjCAtDefsFieldDecl, ObjCIvarDecl.
const RecordDecl *getParent() const {
- return cast<RecordDecl>(getDeclContext());
+ return dyn_cast<RecordDecl>(getDeclContext());
}
RecordDecl *getParent() {
- return cast<RecordDecl>(getDeclContext());
+ return dyn_cast<RecordDecl>(getDeclContext());
}
SourceRange getSourceRange() const override LLVM_READONLY;
@@ -3534,6 +3554,7 @@ class EnumDecl : public TagDecl {
/// negative enumerators of this enum. (see getNumNegativeBits)
void setNumNegativeBits(unsigned Num) { EnumDeclBits.NumNegativeBits = Num; }
+public:
/// True if this tag declaration is a scoped enumeration. Only
/// possible in C++11 mode.
void setScoped(bool Scoped = true) { EnumDeclBits.IsScoped = Scoped; }
@@ -3550,6 +3571,7 @@ class EnumDecl : public TagDecl {
/// Microsoft-style enumeration with a fixed underlying type.
void setFixed(bool Fixed = true) { EnumDeclBits.IsFixed = Fixed; }
+private:
/// True if a valid hash is stored in ODRHash.
bool hasODRHash() const { return EnumDeclBits.HasODRHash; }
void setHasODRHash(bool Hash = true) { EnumDeclBits.HasODRHash = Hash; }
@@ -3954,6 +3976,11 @@ public:
return cast_or_null<RecordDecl>(TagDecl::getDefinition());
}
+ /// Returns whether this record is a union, or contains (at any nesting level)
+ /// a union member. This is used by CMSE to warn about possible information
+ /// leaks.
+ bool isOrContainsUnion() const;
+
// Iterator access to field members. The field iterator only visits
// the non-static data members of this class, ignoring any static
// data members, functions, constructors, destructors, etc.
@@ -4335,17 +4362,18 @@ class ImportDecl final : public Decl,
friend class ASTReader;
friend TrailingObjects;
- /// The imported module, along with a bit that indicates whether
- /// we have source-location information for each identifier in the module
- /// name.
- ///
- /// When the bit is false, we only have a single source location for the
- /// end of the import declaration.
- llvm::PointerIntPair<Module *, 1, bool> ImportedAndComplete;
+ /// The imported module.
+ Module *ImportedModule = nullptr;
/// The next import in the list of imports local to the translation
/// unit being parsed (not loaded from an AST file).
- ImportDecl *NextLocalImport = nullptr;
+ ///
+ /// Includes a bit that indicates whether we have source-location information
+ /// for each identifier in the module name.
+ ///
+ /// When the bit is false, we only have a single source location for the
+ /// end of the import declaration.
+ llvm::PointerIntPair<ImportDecl *, 1, bool> NextLocalImportAndComplete;
ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs);
@@ -4355,6 +4383,20 @@ class ImportDecl final : public Decl,
ImportDecl(EmptyShell Empty) : Decl(Import, Empty) {}
+ bool isImportComplete() const { return NextLocalImportAndComplete.getInt(); }
+
+ void setImportComplete(bool C) { NextLocalImportAndComplete.setInt(C); }
+
+ /// The next import in the list of imports local to the translation
+ /// unit being parsed (not loaded from an AST file).
+ ImportDecl *getNextLocalImport() const {
+ return NextLocalImportAndComplete.getPointer();
+ }
+
+ void setNextLocalImport(ImportDecl *Import) {
+ NextLocalImportAndComplete.setPointer(Import);
+ }
+
public:
/// Create a new module import declaration.
static ImportDecl *Create(ASTContext &C, DeclContext *DC,
@@ -4372,7 +4414,7 @@ public:
unsigned NumLocations);
/// Retrieve the module that was imported by the import declaration.
- Module *getImportedModule() const { return ImportedAndComplete.getPointer(); }
+ Module *getImportedModule() const { return ImportedModule; }
/// Retrieves the locations of each of the identifiers that make up
/// the complete module name in the import declaration.
@@ -4520,6 +4562,13 @@ inline bool IsEnumDeclScoped(EnumDecl *ED) {
return ED->isScoped();
}
+/// OpenMP variants are mangled early based on their OpenMP context selector.
+/// The new name looks likes this:
+/// <name> + OpenMPVariantManglingSeparatorStr + <mangled OpenMP context>
+static constexpr StringRef getOpenMPVariantManglingSeparatorStr() {
+ return "$ompvariant";
+}
+
} // namespace clang
#endif // LLVM_CLANG_AST_DECL_H
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index 91c372585b07..4f33ff104ffd 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -66,6 +66,7 @@ class SourceManager;
class Stmt;
class StoredDeclsMap;
class TemplateDecl;
+class TemplateParameterList;
class TranslationUnitDecl;
class UsingDirectiveDecl;
@@ -465,6 +466,10 @@ public:
ASTContext &getASTContext() const LLVM_READONLY;
+ /// Helper to get the language options from the ASTContext.
+ /// Defined out of line to avoid depending on ASTContext.h.
+ const LangOptions &getLangOpts() const LLVM_READONLY;
+
void setAccess(AccessSpecifier AS) {
Access = AS;
assert(AccessDeclContextSanity());
@@ -514,7 +519,7 @@ public:
if (!HasAttrs) return;
AttrVec &Vec = getAttrs();
- Vec.erase(std::remove_if(Vec.begin(), Vec.end(), isa<T, Attr*>), Vec.end());
+ llvm::erase_if(Vec, [](Attr *A) { return isa<T>(A); });
if (Vec.empty())
HasAttrs = false;
@@ -626,7 +631,16 @@ protected:
setModuleOwnershipKind(ModuleOwnershipKind::ModulePrivate);
}
- /// Set the owning module ID.
+public:
+ /// Set the FromASTFile flag. This indicates that this declaration
+ /// was deserialized and not parsed from source code and enables
+ /// features such as module ownership information.
+ void setFromASTFile() {
+ FromASTFile = true;
+ }
+
+ /// Set the owning module ID. This may only be called for
+ /// deserialized Decls.
void setOwningModuleID(unsigned ID) {
assert(isFromASTFile() && "Only works on a deserialized declaration");
*((unsigned*)this - 2) = ID;
@@ -767,18 +781,19 @@ public:
/// all declarations in a global module fragment are unowned.
Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const;
- /// Determine whether this declaration might be hidden from name
- /// lookup. Note that the declaration might be visible even if this returns
- /// \c false, if the owning module is visible within the query context.
- // FIXME: Rename this to make it clearer what it does.
- bool isHidden() const {
- return (int)getModuleOwnershipKind() > (int)ModuleOwnershipKind::Visible;
+ /// Determine whether this declaration is definitely visible to name lookup,
+ /// independent of whether the owning module is visible.
+ /// Note: The declaration may be visible even if this returns \c false if the
+ /// owning module is visible within the query context. This is a low-level
+ /// helper function; most code should be calling Sema::isVisible() instead.
+ bool isUnconditionallyVisible() const {
+ return (int)getModuleOwnershipKind() <= (int)ModuleOwnershipKind::Visible;
}
/// Set that this declaration is globally visible, even if it came from a
/// module that is not visible.
void setVisibleDespiteOwningModule() {
- if (isHidden())
+ if (!isUnconditionallyVisible())
setModuleOwnershipKind(ModuleOwnershipKind::Visible);
}
@@ -848,6 +863,10 @@ public:
// within the scope of a template parameter).
bool isTemplated() const;
+ /// Determine the number of levels of template parameter surrounding this
+ /// declaration.
+ unsigned getTemplateDepth() const;
+
/// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
/// scoped decl is defined outside the current function or method. This is
/// roughly global variables and functions, but also handles enums (which
@@ -856,14 +875,19 @@ public:
return getParentFunctionOrMethod() == nullptr;
}
- /// Returns true if this declaration lexically is inside a function.
- /// It recognizes non-defining declarations as well as members of local
- /// classes:
+ /// Determine whether a substitution into this declaration would occur as
+ /// part of a substitution into a dependent local scope. Such a substitution
+ /// transitively substitutes into all constructs nested within this
+ /// declaration.
+ ///
+ /// This recognizes non-defining declarations as well as members of local
+ /// classes and lambdas:
/// \code
- /// void foo() { void bar(); }
- /// void foo2() { class ABC { void bar(); }; }
+ /// template<typename T> void foo() { void bar(); }
+ /// template<typename T> void foo2() { class ABC { void bar(); }; }
+ /// template<typename T> inline int x = [](){ return 0; }();
/// \endcode
- bool isLexicallyWithinFunctionOrMethod() const;
+ bool isInLocalScopeForInstantiation() const;
/// If this decl is defined inside a function/method/block it returns
/// the corresponding DeclContext, otherwise it returns null.
@@ -1023,8 +1047,16 @@ public:
/// If this is a declaration that describes some template, this
/// method returns that template declaration.
+ ///
+ /// Note that this returns nullptr for partial specializations, because they
+ /// are not modeled as TemplateDecls. Use getDescribedTemplateParams to handle
+ /// those cases.
TemplateDecl *getDescribedTemplate() const;
+ /// If this is a declaration that describes some template or partial
+ /// specialization, this returns the corresponding template parameter list.
+ const TemplateParameterList *getDescribedTemplateParams() const;
+
/// Returns the function itself, or the templated function if this is a
/// function template.
FunctionDecl *getAsFunction() LLVM_READONLY;
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index b716ea453a5a..2b8d7e879a0a 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -15,7 +15,6 @@
#ifndef LLVM_CLANG_AST_DECLCXX_H
#define LLVM_CLANG_AST_DECLCXX_H
-#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTUnresolvedSet.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
@@ -40,6 +39,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
@@ -53,6 +53,7 @@
namespace clang {
+class ASTContext;
class ClassTemplateDecl;
class ConstructorUsingShadowDecl;
class CXXBasePath;
@@ -712,6 +713,13 @@ public:
}
/// \c true if we know for sure that this class has a single,
+ /// accessible, unambiguous copy assignment operator that is not deleted.
+ bool hasSimpleCopyAssignment() const {
+ return !hasUserDeclaredCopyAssignment() &&
+ !data().DefaultedCopyAssignmentIsDeleted;
+ }
+
+ /// \c true if we know for sure that this class has a single,
/// accessible, unambiguous move assignment operator that is not deleted.
bool hasSimpleMoveAssignment() const {
return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() &&
@@ -871,6 +879,15 @@ public:
return data().UserDeclaredSpecialMembers & SMF_CopyAssignment;
}
+ /// Set that we attempted to declare an implicit copy assignment
+ /// operator, but overload resolution failed so we deleted it.
+ void setImplicitCopyAssignmentIsDeleted() {
+ assert((data().DefaultedCopyAssignmentIsDeleted ||
+ needsOverloadResolutionForCopyAssignment()) &&
+ "copy assignment should not be deleted");
+ data().DefaultedCopyAssignmentIsDeleted = true;
+ }
+
/// Determine whether this class needs an implicit copy
/// assignment operator to be lazily declared.
bool needsImplicitCopyAssignment() const {
@@ -880,7 +897,16 @@ public:
/// Determine whether we need to eagerly declare a defaulted copy
/// assignment operator for this class.
bool needsOverloadResolutionForCopyAssignment() const {
- return data().HasMutableFields;
+ // C++20 [class.copy.assign]p2:
+ // If the class definition declares a move constructor or move assignment
+ // operator, the implicitly declared copy assignment operator is defined
+ // as deleted.
+ // In MSVC mode, sometimes a declared move constructor does not delete an
+ // implicit copy assignment, so defer this choice to Sema.
+ if (data().UserDeclaredSpecialMembers &
+ (SMF_MoveConstructor | SMF_MoveAssignment))
+ return true;
+ return data().NeedOverloadResolutionForCopyAssignment;
}
/// Determine whether an implicit copy assignment operator for this
@@ -998,6 +1024,9 @@ public:
return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault);
}
+ /// Set the captures for this lambda closure type.
+ void setCaptures(ArrayRef<LambdaCapture> Captures);
+
/// For a closure type, retrieve the mapping from captured
/// variables and \c this to the non-static data members that store the
/// values or references of the captures.
@@ -1029,6 +1058,8 @@ public:
: nullptr;
}
+ unsigned capture_size() const { return getLambdaData().NumCaptures; }
+
using conversion_iterator = UnresolvedSetIterator;
conversion_iterator conversion_begin() const {
@@ -1166,7 +1197,7 @@ public:
bool defaultedDefaultConstructorIsConstexpr() const {
return data().DefaultedDefaultConstructorIsConstexpr &&
(!isUnion() || hasInClassInitializer() || !hasVariantMembers() ||
- getASTContext().getLangOpts().CPlusPlus2a);
+ getLangOpts().CPlusPlus20);
}
/// Determine whether this class has a constexpr default constructor.
@@ -1258,7 +1289,7 @@ public:
/// would be constexpr.
bool defaultedDestructorIsConstexpr() const {
return data().DefaultedDestructorIsConstexpr &&
- getASTContext().getLangOpts().CPlusPlus2a;
+ getLangOpts().CPlusPlus20;
}
/// Determine whether this class has a constexpr destructor.
@@ -1355,10 +1386,10 @@ public:
///
/// Only in C++17 and beyond, are lambdas literal types.
bool isLiteral() const {
- ASTContext &Ctx = getASTContext();
- return (Ctx.getLangOpts().CPlusPlus2a ? hasConstexprDestructor()
+ const LangOptions &LangOpts = getLangOpts();
+ return (LangOpts.CPlusPlus20 ? hasConstexprDestructor()
: hasTrivialDestructor()) &&
- (!isLambda() || Ctx.getLangOpts().CPlusPlus17) &&
+ (!isLambda() || LangOpts.CPlusPlus17) &&
!hasNonLiteralTypeFieldsOrBases() &&
(isAggregate() || isLambda() ||
hasConstexprNonCopyMoveConstructor() ||
@@ -1517,14 +1548,8 @@ public:
/// returns false if the class has non-computable base classes.
///
/// \param BaseMatches Callback invoked for each (direct or indirect) base
- /// class of this type, or if \p AllowShortCircuit is true then until a call
- /// returns false.
- ///
- /// \param AllowShortCircuit if false, forces the callback to be called
- /// for every base class, even if a dependent or non-matching base was
- /// found.
- bool forallBases(ForallBasesCallback BaseMatches,
- bool AllowShortCircuit = true) const;
+ /// class of this type until a call returns false.
+ bool forallBases(ForallBasesCallback BaseMatches) const;
/// Function type used by lookupInBases() to determine whether a
/// specific base class subobject matches the lookup criteria.
@@ -1696,6 +1721,10 @@ public:
/// actually abstract.
bool mayBeAbstract() const;
+ /// Determine whether it's impossible for a class to be derived from this
+ /// class. This is best-effort, and may conservatively return false.
+ bool isEffectivelyFinal() const;
+
/// If this is the closure type of a lambda expression, retrieve the
/// number to be used for name mangling in the Itanium C++ ABI.
///
@@ -1893,6 +1922,37 @@ public:
static bool classofKind(Kind K) { return K == CXXDeductionGuide; }
};
+/// \brief Represents the body of a requires-expression.
+///
+/// This decl exists merely to serve as the DeclContext for the local
+/// parameters of the requires expression as well as other declarations inside
+/// it.
+///
+/// \code
+/// template<typename T> requires requires (T t) { {t++} -> regular; }
+/// \endcode
+///
+/// In this example, a RequiresExpr object will be generated for the expression,
+/// and a RequiresExprBodyDecl will be created to hold the parameter t and the
+/// template argument list imposed by the compound requirement.
+class RequiresExprBodyDecl : public Decl, public DeclContext {
+ RequiresExprBodyDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc)
+ : Decl(RequiresExprBody, DC, StartLoc), DeclContext(RequiresExprBody) {}
+
+public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
+ static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc);
+
+ static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == RequiresExprBody; }
+};
+
/// Represents a static or instance method of a struct/union/class.
///
/// In the terminology of the C++ Standard, these are the (static and
@@ -2006,7 +2066,8 @@ public:
method_iterator end_overridden_methods() const;
unsigned size_overridden_methods() const;
- using overridden_method_range= ASTContext::overridden_method_range;
+ using overridden_method_range = llvm::iterator_range<
+ llvm::TinyPtrVector<const CXXMethodDecl *>::const_iterator>;
overridden_method_range overridden_methods() const;
@@ -2386,17 +2447,6 @@ class CXXConstructorDecl final
: ExplicitSpecKind::ResolvedFalse);
}
- void setExplicitSpecifier(ExplicitSpecifier ES) {
- assert((!ES.getExpr() ||
- CXXConstructorDeclBits.HasTrailingExplicitSpecifier) &&
- "cannot set this explicit specifier. no trail-allocated space for "
- "explicit");
- if (ES.getExpr())
- *getCanonicalDecl()->getTrailingObjects<ExplicitSpecifier>() = ES;
- else
- CXXConstructorDeclBits.IsSimpleExplicit = ES.isExplicit();
- }
-
enum TraillingAllocKind {
TAKInheritsConstructor = 1,
TAKHasTailExplicit = 1 << 1,
@@ -2422,6 +2472,17 @@ public:
InheritedConstructor Inherited = InheritedConstructor(),
Expr *TrailingRequiresClause = nullptr);
+ void setExplicitSpecifier(ExplicitSpecifier ES) {
+ assert((!ES.getExpr() ||
+ CXXConstructorDeclBits.HasTrailingExplicitSpecifier) &&
+ "cannot set this explicit specifier. no trail-allocated space for "
+ "explicit");
+ if (ES.getExpr())
+ *getCanonicalDecl()->getTrailingObjects<ExplicitSpecifier>() = ES;
+ else
+ CXXConstructorDeclBits.IsSimpleExplicit = ES.isExplicit();
+ }
+
ExplicitSpecifier getExplicitSpecifier() {
return getCanonicalDecl()->getExplicitSpecifierInternal();
}
@@ -2693,8 +2754,6 @@ class CXXConversionDecl : public CXXMethodDecl {
ExplicitSpecifier ExplicitSpec;
- void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; }
-
public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
@@ -2716,6 +2775,7 @@ public:
/// Return true if the declartion is already resolved to be explicit.
bool isExplicit() const { return getExplicitSpecifier().isExplicit(); }
+ void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; }
/// Returns the type that this conversion function is converting to.
QualType getConversionType() const {
@@ -3933,6 +3993,81 @@ public:
IdentifierInfo* getSetterId() const { return SetterId; }
};
+/// Parts of a decomposed MSGuidDecl. Factored out to avoid unnecessary
+/// dependencies on DeclCXX.h.
+struct MSGuidDeclParts {
+ /// {01234567-...
+ uint32_t Part1;
+ /// ...-89ab-...
+ uint16_t Part2;
+ /// ...-cdef-...
+ uint16_t Part3;
+ /// ...-0123-456789abcdef}
+ uint8_t Part4And5[8];
+
+ uint64_t getPart4And5AsUint64() const {
+ uint64_t Val;
+ memcpy(&Val, &Part4And5, sizeof(Part4And5));
+ return Val;
+ }
+};
+
+/// A global _GUID constant. These are implicitly created by UuidAttrs.
+///
+/// struct _declspec(uuid("01234567-89ab-cdef-0123-456789abcdef")) X{};
+///
+/// X is a CXXRecordDecl that contains a UuidAttr that references the (unique)
+/// MSGuidDecl for the specified UUID.
+class MSGuidDecl : public ValueDecl,
+ public Mergeable<MSGuidDecl>,
+ public llvm::FoldingSetNode {
+public:
+ using Parts = MSGuidDeclParts;
+
+private:
+ /// The decomposed form of the UUID.
+ Parts PartVal;
+
+ /// The resolved value of the UUID as an APValue. Computed on demand and
+ /// cached.
+ mutable APValue APVal;
+
+ void anchor() override;
+
+ MSGuidDecl(DeclContext *DC, QualType T, Parts P);
+
+ static MSGuidDecl *Create(const ASTContext &C, QualType T, Parts P);
+ static MSGuidDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ // Only ASTContext::getMSGuidDecl and deserialization create these.
+ friend class ASTContext;
+ friend class ASTReader;
+ friend class ASTDeclReader;
+
+public:
+ /// Print this UUID in a human-readable format.
+ void printName(llvm::raw_ostream &OS) const override;
+
+ /// Get the decomposed parts of this declaration.
+ Parts getParts() const { return PartVal; }
+
+ /// Get the value of this MSGuidDecl as an APValue. This may fail and return
+ /// an absent APValue if the type of the declaration is not of the expected
+ /// shape.
+ APValue &getAsAPValue() const;
+
+ static void Profile(llvm::FoldingSetNodeID &ID, Parts P) {
+ ID.AddInteger(P.Part1);
+ ID.AddInteger(P.Part2);
+ ID.AddInteger(P.Part3);
+ ID.AddInteger(P.getPart4And5AsUint64());
+ }
+ void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, PartVal); }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == Decl::MSGuid; }
+};
+
/// Insertion operator for diagnostics. This allows sending an AccessSpecifier
/// into a diagnostic with <<.
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
diff --git a/clang/include/clang/AST/DeclGroup.h b/clang/include/clang/AST/DeclGroup.h
index 2be9dae9431e..672b7b0a9fe2 100644
--- a/clang/include/clang/AST/DeclGroup.h
+++ b/clang/include/clang/AST/DeclGroup.h
@@ -147,7 +147,7 @@ namespace llvm {
return clang::DeclGroupRef::getFromOpaquePtr(P);
}
- enum { NumLowBitsAvailable = 0 };
+ static constexpr int NumLowBitsAvailable = 0;
};
} // namespace llvm
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index b98aef6b499d..5613ed8370c0 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -15,6 +15,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclObjCCommon.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/Redeclarable.h"
#include "clang/AST/SelectorLocationsKind.h"
@@ -402,7 +403,7 @@ public:
}
/// createImplicitParams - Used to lazily create the self and cmd
- /// implict parameters. This must be called prior to using getSelfDecl()
+ /// implicit parameters. This must be called prior to using getSelfDecl()
/// or getCmdDecl(). The call is ignored if the implicit parameters
/// have already been created.
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
@@ -742,34 +743,6 @@ class ObjCPropertyDecl : public NamedDecl {
void anchor() override;
public:
- enum PropertyAttributeKind {
- OBJC_PR_noattr = 0x00,
- OBJC_PR_readonly = 0x01,
- OBJC_PR_getter = 0x02,
- OBJC_PR_assign = 0x04,
- OBJC_PR_readwrite = 0x08,
- OBJC_PR_retain = 0x10,
- OBJC_PR_copy = 0x20,
- OBJC_PR_nonatomic = 0x40,
- OBJC_PR_setter = 0x80,
- OBJC_PR_atomic = 0x100,
- OBJC_PR_weak = 0x200,
- OBJC_PR_strong = 0x400,
- OBJC_PR_unsafe_unretained = 0x800,
- /// Indicates that the nullability of the type was spelled with a
- /// property attribute rather than a type qualifier.
- OBJC_PR_nullability = 0x1000,
- OBJC_PR_null_resettable = 0x2000,
- OBJC_PR_class = 0x4000,
- OBJC_PR_direct = 0x8000
- // Adding a property should change NumPropertyAttrsBits
- };
-
- enum {
- /// Number of bits fitting all the property attributes.
- NumPropertyAttrsBits = 16
- };
-
enum SetterKind { Assign, Retain, Copy, Weak };
enum PropertyControl { None, Required, Optional };
@@ -782,8 +755,8 @@ private:
QualType DeclType;
TypeSourceInfo *DeclTypeSourceInfo;
- unsigned PropertyAttributes : NumPropertyAttrsBits;
- unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
+ unsigned PropertyAttributes : NumObjCPropertyAttrsBits;
+ unsigned PropertyAttributesAsWritten : NumObjCPropertyAttrsBits;
// \@required/\@optional
unsigned PropertyImplementation : 2;
@@ -810,15 +783,14 @@ private:
ObjCIvarDecl *PropertyIvarDecl = nullptr;
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- SourceLocation AtLocation, SourceLocation LParenLocation,
- QualType T, TypeSourceInfo *TSI,
- PropertyControl propControl)
- : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
- LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
- PropertyAttributes(OBJC_PR_noattr),
- PropertyAttributesAsWritten(OBJC_PR_noattr),
- PropertyImplementation(propControl), GetterName(Selector()),
- SetterName(Selector()) {}
+ SourceLocation AtLocation, SourceLocation LParenLocation,
+ QualType T, TypeSourceInfo *TSI, PropertyControl propControl)
+ : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
+ LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
+ PropertyAttributes(ObjCPropertyAttribute::kind_noattr),
+ PropertyAttributesAsWritten(ObjCPropertyAttribute::kind_noattr),
+ PropertyImplementation(propControl), GetterName(Selector()),
+ SetterName(Selector()) {}
public:
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
@@ -850,11 +822,11 @@ public:
/// type.
QualType getUsageType(QualType objectType) const;
- PropertyAttributeKind getPropertyAttributes() const {
- return PropertyAttributeKind(PropertyAttributes);
+ ObjCPropertyAttribute::Kind getPropertyAttributes() const {
+ return ObjCPropertyAttribute::Kind(PropertyAttributes);
}
- void setPropertyAttributes(PropertyAttributeKind PRVal) {
+ void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal) {
PropertyAttributes |= PRVal;
}
@@ -862,11 +834,11 @@ public:
PropertyAttributes = PRVal;
}
- PropertyAttributeKind getPropertyAttributesAsWritten() const {
- return PropertyAttributeKind(PropertyAttributesAsWritten);
+ ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const {
+ return ObjCPropertyAttribute::Kind(PropertyAttributesAsWritten);
}
- void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
+ void setPropertyAttributesAsWritten(ObjCPropertyAttribute::Kind PRVal) {
PropertyAttributesAsWritten = PRVal;
}
@@ -874,23 +846,28 @@ public:
/// isReadOnly - Return true iff the property has a setter.
bool isReadOnly() const {
- return (PropertyAttributes & OBJC_PR_readonly);
+ return (PropertyAttributes & ObjCPropertyAttribute::kind_readonly);
}
/// isAtomic - Return true if the property is atomic.
bool isAtomic() const {
- return (PropertyAttributes & OBJC_PR_atomic);
+ return (PropertyAttributes & ObjCPropertyAttribute::kind_atomic);
}
/// isRetaining - Return true if the property retains its value.
bool isRetaining() const {
- return (PropertyAttributes &
- (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
+ return (PropertyAttributes & (ObjCPropertyAttribute::kind_retain |
+ ObjCPropertyAttribute::kind_strong |
+ ObjCPropertyAttribute::kind_copy));
}
bool isInstanceProperty() const { return !isClassProperty(); }
- bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; }
- bool isDirectProperty() const { return PropertyAttributes & OBJC_PR_direct; }
+ bool isClassProperty() const {
+ return PropertyAttributes & ObjCPropertyAttribute::kind_class;
+ }
+ bool isDirectProperty() const {
+ return PropertyAttributes & ObjCPropertyAttribute::kind_direct;
+ }
ObjCPropertyQueryKind getQueryKind() const {
return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class :
@@ -906,13 +883,13 @@ public:
/// the property setter. This is only valid if the property has been
/// defined to have a setter.
SetterKind getSetterKind() const {
- if (PropertyAttributes & OBJC_PR_strong)
+ if (PropertyAttributes & ObjCPropertyAttribute::kind_strong)
return getType()->isBlockPointerType() ? Copy : Retain;
- if (PropertyAttributes & OBJC_PR_retain)
+ if (PropertyAttributes & ObjCPropertyAttribute::kind_retain)
return Retain;
- if (PropertyAttributes & OBJC_PR_copy)
+ if (PropertyAttributes & ObjCPropertyAttribute::kind_copy)
return Copy;
- if (PropertyAttributes & OBJC_PR_weak)
+ if (PropertyAttributes & ObjCPropertyAttribute::kind_weak)
return Weak;
return Assign;
}
@@ -2692,9 +2669,7 @@ public:
/// Get the name of the class associated with this interface.
//
// FIXME: Move to StringRef API.
- std::string getNameAsString() const {
- return getName();
- }
+ std::string getNameAsString() const { return std::string(getName()); }
/// Produce a name to be used for class's metadata. It comes either via
/// class's objc_runtime_name attribute or class name.
@@ -2908,11 +2883,11 @@ ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() {
}
inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
- return !Cat->isHidden();
+ return Cat->isUnconditionallyVisible();
}
inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension() && !Cat->isHidden();
+ return Cat->IsClassExtension() && Cat->isUnconditionallyVisible();
}
inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
diff --git a/clang/include/clang/AST/DeclObjCCommon.h b/clang/include/clang/AST/DeclObjCCommon.h
new file mode 100644
index 000000000000..5f03bce6e9a8
--- /dev/null
+++ b/clang/include/clang/AST/DeclObjCCommon.h
@@ -0,0 +1,55 @@
+//===- DeclObjCCommon.h - Classes for representing declarations -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains common ObjC enums and classes used in AST and
+// Sema.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLOBJC_COMMON_H
+#define LLVM_CLANG_AST_DECLOBJC_COMMON_H
+
+namespace clang {
+
+/// ObjCPropertyAttribute::Kind - list of property attributes.
+/// Keep this list in sync with LLVM's Dwarf.h ApplePropertyAttributes.s
+namespace ObjCPropertyAttribute {
+enum Kind {
+ kind_noattr = 0x00,
+ kind_readonly = 0x01,
+ kind_getter = 0x02,
+ kind_assign = 0x04,
+ kind_readwrite = 0x08,
+ kind_retain = 0x10,
+ kind_copy = 0x20,
+ kind_nonatomic = 0x40,
+ kind_setter = 0x80,
+ kind_atomic = 0x100,
+ kind_weak = 0x200,
+ kind_strong = 0x400,
+ kind_unsafe_unretained = 0x800,
+ /// Indicates that the nullability of the type was spelled with a
+ /// property attribute rather than a type qualifier.
+ kind_nullability = 0x1000,
+ kind_null_resettable = 0x2000,
+ kind_class = 0x4000,
+ kind_direct = 0x8000,
+ // Adding a property should change NumObjCPropertyAttrsBits
+ // Also, don't forget to update the Clang C API at CXObjCPropertyAttrKind and
+ // clang_Cursor_getObjCPropertyAttributes.
+};
+} // namespace ObjCPropertyAttribute::Kind
+
+enum {
+ /// Number of bits fitting all the property attributes.
+ NumObjCPropertyAttrsBits = 16
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_DECLOBJC_COMMON_H
diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h
index 437feaba28fb..154ecb977692 100644
--- a/clang/include/clang/AST/DeclOpenMP.h
+++ b/clang/include/clang/AST/DeclOpenMP.h
@@ -129,7 +129,7 @@ private:
/// the declare reduction construct is declared inside compound statement.
LazyDeclPtr PrevDeclInScope;
- virtual void anchor();
+ void anchor() override;
OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name, QualType Ty,
@@ -228,7 +228,7 @@ class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext {
LazyDeclPtr PrevDeclInScope;
- virtual void anchor();
+ void anchor() override;
OMPDeclareMapperDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name, QualType Ty,
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index 7a55d04a0f35..e9c4879b41e8 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -1102,6 +1102,17 @@ public:
/// template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
+ /// Return whether this function template is an abbreviated function template,
+ /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
+ bool isAbbreviated() const {
+ // Since the invented template parameters generated from 'auto' parameters
+ // are either appended to the end of the explicit template parameter list or
+ // form a new template paramter list, we can simply observe the last
+ // parameter to determine if such a thing happened.
+ const TemplateParameterList *TPL = getTemplateParameters();
+ return TPL->getParam(TPL->size() - 1)->isImplicit();
+ }
+
/// Merge \p Prev with our RedeclarableTemplateDecl::Common.
void mergePrevDecl(FunctionTemplateDecl *Prev);
@@ -1215,7 +1226,6 @@ public:
bool ParameterPack,
bool HasTypeConstraint = false,
Optional<unsigned> NumExpanded = None);
-
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
unsigned ID);
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
@@ -1374,7 +1384,8 @@ class NonTypeTemplateParmDecl final
: public DeclaratorDecl,
protected TemplateParmPosition,
private llvm::TrailingObjects<NonTypeTemplateParmDecl,
- std::pair<QualType, TypeSourceInfo *>> {
+ std::pair<QualType, TypeSourceInfo *>,
+ Expr *> {
friend class ASTDeclReader;
friend TrailingObjects;
@@ -1429,10 +1440,12 @@ public:
ArrayRef<TypeSourceInfo *> ExpandedTInfos);
static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
+ unsigned ID,
+ bool HasTypeConstraint);
static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
unsigned ID,
- unsigned NumExpandedTypes);
+ unsigned NumExpandedTypes,
+ bool HasTypeConstraint);
using TemplateParmPosition::getDepth;
using TemplateParmPosition::setDepth;
@@ -1543,20 +1556,22 @@ public:
return TypesAndInfos[I].second;
}
- /// Return the type-constraint in the placeholder type of this non-type
+ /// Return the constraint introduced by the placeholder type of this non-type
/// template parameter (if any).
- TypeConstraint *getPlaceholderTypeConstraint() const {
- // TODO: Concepts: Implement once we have actual placeholders with type
- // constraints.
- return nullptr;
+ Expr *getPlaceholderTypeConstraint() const {
+ return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
+ nullptr;
+ }
+
+ void setPlaceholderTypeConstraint(Expr *E) {
+ *getTrailingObjects<Expr *>() = E;
}
/// Determine whether this non-type template parameter's type has a
/// placeholder with a type-constraint.
bool hasPlaceholderTypeConstraint() const {
- // TODO: Concepts: Implement once we have actual placeholders with type
- // constraints.
- return false;
+ auto *AT = getType()->getContainedAutoType();
+ return AT && AT->isConstrained();
}
/// \brief Get the associated-constraints of this template parameter.
@@ -1566,8 +1581,8 @@ public:
/// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
/// concepts APIs that accept an ArrayRef of constraint expressions.
void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
- if (TypeConstraint *TC = getPlaceholderTypeConstraint())
- AC.push_back(TC->getImmediatelyDeclaredConstraint());
+ if (Expr *E = getPlaceholderTypeConstraint())
+ AC.push_back(E);
}
// Implement isa/cast/dyncast/etc.
@@ -1876,6 +1891,10 @@ public:
return *TemplateArgs;
}
+ void setTemplateArgs(TemplateArgumentList *Args) {
+ TemplateArgs = Args;
+ }
+
/// Determine the kind of specialization that this
/// declaration represents.
TemplateSpecializationKind getSpecializationKind() const {
@@ -1908,6 +1927,10 @@ public:
getTemplateSpecializationKind());
}
+ void setSpecializedTemplate(ClassTemplateDecl *Specialized) {
+ SpecializedTemplate = Specialized;
+ }
+
void setSpecializationKind(TemplateSpecializationKind TSK) {
SpecializationKind = TSK;
}
diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h
new file mode 100644
index 000000000000..14a7ffaecb2b
--- /dev/null
+++ b/clang/include/clang/AST/DependenceFlags.h
@@ -0,0 +1,284 @@
+//===--- DependenceFlags.h ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DEPENDENCEFLAGS_H
+#define LLVM_CLANG_AST_DEPENDENCEFLAGS_H
+
+#include "clang/Basic/BitmaskEnum.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include <cstdint>
+
+namespace clang {
+struct ExprDependenceScope {
+ enum ExprDependence : uint8_t {
+ UnexpandedPack = 1,
+ // This expr depends in any way on
+ // - a template parameter, it implies that the resolution of this expr may
+ // cause instantiation to fail
+ // - or an error (often in a non-template context)
+ //
+ // Note that C++ standard doesn't define the instantiation-dependent term,
+ // we follow the formal definition coming from the Itanium C++ ABI, and
+ // extend it to errors.
+ Instantiation = 2,
+ // The type of this expr depends on a template parameter, or an error.
+ Type = 4,
+ // The value of this expr depends on a template parameter, or an error.
+ Value = 8,
+
+ // clang extension: this expr contains or references an error, and is
+ // considered dependent on how that error is resolved.
+ Error = 16,
+
+ None = 0,
+ All = 31,
+
+ TypeValue = Type | Value,
+ TypeInstantiation = Type | Instantiation,
+ ValueInstantiation = Value | Instantiation,
+ TypeValueInstantiation = Type | Value | Instantiation,
+
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
+ };
+};
+using ExprDependence = ExprDependenceScope::ExprDependence;
+
+struct TypeDependenceScope {
+ enum TypeDependence : uint8_t {
+ /// Whether this type contains an unexpanded parameter pack
+ /// (for C++11 variadic templates)
+ UnexpandedPack = 1,
+ /// Whether this type somehow involves
+ /// - a template parameter, even if the resolution of the type does not
+ /// depend on a template parameter.
+ /// - or an error.
+ Instantiation = 2,
+ /// Whether this type
+ /// - is a dependent type (C++ [temp.dep.type])
+ /// - or it somehow involves an error, e.g. decltype(recovery-expr)
+ Dependent = 4,
+ /// Whether this type is a variably-modified type (C99 6.7.5).
+ VariablyModified = 8,
+
+ /// Whether this type references an error, e.g. decltype(err-expression)
+ /// yields an error type.
+ Error = 16,
+
+ None = 0,
+ All = 31,
+
+ DependentInstantiation = Dependent | Instantiation,
+
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
+ };
+};
+using TypeDependence = TypeDependenceScope::TypeDependence;
+
+#define LLVM_COMMON_DEPENDENCE(NAME) \
+ struct NAME##Scope { \
+ enum NAME : uint8_t { \
+ UnexpandedPack = 1, \
+ Instantiation = 2, \
+ Dependent = 4, \
+ Error = 8, \
+ \
+ None = 0, \
+ DependentInstantiation = Dependent | Instantiation, \
+ All = 15, \
+ \
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) \
+ }; \
+ }; \
+ using NAME = NAME##Scope::NAME;
+
+LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence)
+LLVM_COMMON_DEPENDENCE(TemplateNameDependence)
+LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence)
+#undef LLVM_COMMON_DEPENDENCE
+
+// A combined space of all dependence concepts for all node types.
+// Used when aggregating dependence of nodes of different types.
+class Dependence {
+public:
+ enum Bits : uint8_t {
+ None = 0,
+
+ // Contains a template parameter pack that wasn't expanded.
+ UnexpandedPack = 1,
+ // Depends on a template parameter or an error in some way.
+ // Validity depends on how the template is instantiated or the error is
+ // resolved.
+ Instantiation = 2,
+ // Expression type depends on template context, or an error.
+ // Value and Instantiation should also be set.
+ Type = 4,
+ // Expression value depends on template context, or an error.
+ // Instantiation should also be set.
+ Value = 8,
+ // Depends on template context, or an error.
+ // The type/value distinction is only meaningful for expressions.
+ Dependent = Type | Value,
+ // Includes an error, and depends on how it is resolved.
+ Error = 16,
+ // Type depends on a runtime value (variable-length array).
+ VariablyModified = 32,
+
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified)
+ };
+
+ Dependence() : V(None) {}
+
+ Dependence(TypeDependence D)
+ : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) |
+ translate(D, TypeDependence::Instantiation, Instantiation) |
+ translate(D, TypeDependence::Dependent, Dependent) |
+ translate(D, TypeDependence::Error, Error) |
+ translate(D, TypeDependence::VariablyModified, VariablyModified)) {}
+
+ Dependence(ExprDependence D)
+ : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) |
+ translate(D, ExprDependence::Instantiation, Instantiation) |
+ translate(D, ExprDependence::Type, Type) |
+ translate(D, ExprDependence::Value, Value) |
+ translate(D, ExprDependence::Error, Error)) {}
+
+ Dependence(NestedNameSpecifierDependence D) :
+ V ( translate(D, NNSDependence::UnexpandedPack, UnexpandedPack) |
+ translate(D, NNSDependence::Instantiation, Instantiation) |
+ translate(D, NNSDependence::Dependent, Dependent) |
+ translate(D, NNSDependence::Error, Error)) {}
+
+ Dependence(TemplateArgumentDependence D)
+ : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) |
+ translate(D, TADependence::Instantiation, Instantiation) |
+ translate(D, TADependence::Dependent, Dependent) |
+ translate(D, TADependence::Error, Error)) {}
+
+ Dependence(TemplateNameDependence D)
+ : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) |
+ translate(D, TNDependence::Instantiation, Instantiation) |
+ translate(D, TNDependence::Dependent, Dependent) |
+ translate(D, TNDependence::Error, Error)) {}
+
+ TypeDependence type() const {
+ return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) |
+ translate(V, Instantiation, TypeDependence::Instantiation) |
+ translate(V, Dependent, TypeDependence::Dependent) |
+ translate(V, Error, TypeDependence::Error) |
+ translate(V, VariablyModified, TypeDependence::VariablyModified);
+ }
+
+ ExprDependence expr() const {
+ return translate(V, UnexpandedPack, ExprDependence::UnexpandedPack) |
+ translate(V, Instantiation, ExprDependence::Instantiation) |
+ translate(V, Type, ExprDependence::Type) |
+ translate(V, Value, ExprDependence::Value) |
+ translate(V, Error, ExprDependence::Error);
+ }
+
+ NestedNameSpecifierDependence nestedNameSpecifier() const {
+ return translate(V, UnexpandedPack, NNSDependence::UnexpandedPack) |
+ translate(V, Instantiation, NNSDependence::Instantiation) |
+ translate(V, Dependent, NNSDependence::Dependent) |
+ translate(V, Error, NNSDependence::Error);
+ }
+
+ TemplateArgumentDependence templateArgument() const {
+ return translate(V, UnexpandedPack, TADependence::UnexpandedPack) |
+ translate(V, Instantiation, TADependence::Instantiation) |
+ translate(V, Dependent, TADependence::Dependent) |
+ translate(V, Error, TADependence::Error);
+ }
+
+ TemplateNameDependence templateName() const {
+ return translate(V, UnexpandedPack, TNDependence::UnexpandedPack) |
+ translate(V, Instantiation, TNDependence::Instantiation) |
+ translate(V, Dependent, TNDependence::Dependent) |
+ translate(V, Error, TNDependence::Error);
+ }
+
+private:
+ Bits V;
+
+ template <typename T, typename U>
+ static U translate(T Bits, T FromBit, U ToBit) {
+ return (Bits & FromBit) ? ToBit : static_cast<U>(0);
+ }
+
+ // Abbreviations to make conversions more readable.
+ using NNSDependence = NestedNameSpecifierDependence;
+ using TADependence = TemplateArgumentDependence;
+ using TNDependence = TemplateNameDependence;
+};
+
+/// Computes dependencies of a reference with the name having template arguments
+/// with \p TA dependencies.
+inline ExprDependence toExprDependence(TemplateArgumentDependence TA) {
+ return Dependence(TA).expr();
+}
+inline ExprDependence toExprDependence(TypeDependence D) {
+ return Dependence(D).expr();
+}
+// Note: it's often necessary to strip `Dependent` from qualifiers.
+// If V<T>:: refers to the current instantiation, NNS is considered dependent
+// but the containing V<T>::foo likely isn't.
+inline ExprDependence toExprDependence(NestedNameSpecifierDependence D) {
+ return Dependence(D).expr();
+}
+inline ExprDependence turnTypeToValueDependence(ExprDependence D) {
+ // Type-dependent expressions are always be value-dependent, so we simply drop
+ // type dependency.
+ return D & ~ExprDependence::Type;
+}
+inline ExprDependence turnValueToTypeDependence(ExprDependence D) {
+ // Type-dependent expressions are always be value-dependent.
+ if (D & ExprDependence::Value)
+ D |= ExprDependence::Type;
+ return D;
+}
+
+// Returned type-dependence will never have VariablyModified set.
+inline TypeDependence toTypeDependence(ExprDependence D) {
+ return Dependence(D).type();
+}
+inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) {
+ return Dependence(D).type();
+}
+inline TypeDependence toTypeDependence(TemplateNameDependence D) {
+ return Dependence(D).type();
+}
+inline TypeDependence toTypeDependence(TemplateArgumentDependence D) {
+ return Dependence(D).type();
+}
+
+inline NestedNameSpecifierDependence
+toNestedNameSpecifierDependendence(TypeDependence D) {
+ return Dependence(D).nestedNameSpecifier();
+}
+
+inline TemplateArgumentDependence
+toTemplateArgumentDependence(TypeDependence D) {
+ return Dependence(D).templateArgument();
+}
+inline TemplateArgumentDependence
+toTemplateArgumentDependence(TemplateNameDependence D) {
+ return Dependence(D).templateArgument();
+}
+inline TemplateArgumentDependence
+toTemplateArgumentDependence(ExprDependence D) {
+ return Dependence(D).templateArgument();
+}
+
+inline TemplateNameDependence
+toTemplateNameDependence(NestedNameSpecifierDependence D) {
+ return Dependence(D).templateName();
+}
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+} // namespace clang
+#endif
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 16956c27a114..c13b97119285 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -15,8 +15,10 @@
#include "clang/AST/APValue.h"
#include "clang/AST/ASTVector.h"
+#include "clang/AST/ComputeDependence.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/DependenceFlags.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/TemplateBase.h"
@@ -28,10 +30,10 @@
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
@@ -116,23 +118,26 @@ public:
Expr &operator=(Expr&&) = delete;
protected:
- Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK,
- bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack)
- : ValueStmt(SC)
- {
- ExprBits.TypeDependent = TD;
- ExprBits.ValueDependent = VD;
- ExprBits.InstantiationDependent = ID;
+ Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK)
+ : ValueStmt(SC) {
+ ExprBits.Dependent = 0;
ExprBits.ValueKind = VK;
ExprBits.ObjectKind = OK;
assert(ExprBits.ObjectKind == OK && "truncated kind");
- ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
setType(T);
}
/// Construct an empty expression.
explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) { }
+ /// Each concrete expr subclass is expected to compute its dependence and call
+ /// this in the constructor.
+ void setDependence(ExprDependence Deps) {
+ ExprBits.Dependent = static_cast<unsigned>(Deps);
+ }
+ friend class ASTImporter; // Sets dependence dircetly.
+ friend class ASTStmtReader; // Sets dependence dircetly.
+
public:
QualType getType() const { return TR; }
void setType(QualType t) {
@@ -148,24 +153,29 @@ public:
TR = t;
}
- /// isValueDependent - Determines whether this expression is
- /// value-dependent (C++ [temp.dep.constexpr]). For example, the
- /// array bound of "Chars" in the following example is
+ ExprDependence getDependence() const {
+ return static_cast<ExprDependence>(ExprBits.Dependent);
+ }
+
+ /// Determines whether the value of this expression depends on
+ /// - a template parameter (C++ [temp.dep.constexpr])
+ /// - or an error, whose resolution is unknown
+ ///
+ /// For example, the array bound of "Chars" in the following example is
/// value-dependent.
/// @code
/// template<int Size, char (&Chars)[Size]> struct meta_string;
/// @endcode
- bool isValueDependent() const { return ExprBits.ValueDependent; }
-
- /// Set whether this expression is value-dependent or not.
- void setValueDependent(bool VD) {
- ExprBits.ValueDependent = VD;
+ bool isValueDependent() const {
+ return static_cast<bool>(getDependence() & ExprDependence::Value);
}
- /// isTypeDependent - Determines whether this expression is
- /// type-dependent (C++ [temp.dep.expr]), which means that its type
- /// could change from one template instantiation to the next. For
- /// example, the expressions "x" and "x + y" are type-dependent in
+ /// Determines whether the type of this expression depends on
+ /// - a template paramter (C++ [temp.dep.expr], which means that its type
+ /// could change from one template instantiation to the next)
+ /// - or an error
+ ///
+ /// For example, the expressions "x" and "x + y" are type-dependent in
/// the following code, but "y" is not type-dependent:
/// @code
/// template<typename T>
@@ -173,16 +183,15 @@ public:
/// x + y;
/// }
/// @endcode
- bool isTypeDependent() const { return ExprBits.TypeDependent; }
-
- /// Set whether this expression is type-dependent or not.
- void setTypeDependent(bool TD) {
- ExprBits.TypeDependent = TD;
+ bool isTypeDependent() const {
+ return static_cast<bool>(getDependence() & ExprDependence::Type);
}
/// Whether this expression is instantiation-dependent, meaning that
- /// it depends in some way on a template parameter, even if neither its type
- /// nor (constant) value can change due to the template instantiation.
+ /// it depends in some way on
+ /// - a template parameter (even if neither its type nor (constant) value
+ /// can change due to the template instantiation)
+ /// - or an error
///
/// In the following example, the expression \c sizeof(sizeof(T() + T())) is
/// instantiation-dependent (since it involves a template parameter \c T), but
@@ -197,13 +206,14 @@ public:
/// }
/// \endcode
///
+ /// \code
+ /// void func(int) {
+ /// func(); // the expression is instantiation-dependent, because it depends
+ /// // on an error.
+ /// }
+ /// \endcode
bool isInstantiationDependent() const {
- return ExprBits.InstantiationDependent;
- }
-
- /// Set whether this expression is instantiation-dependent or not.
- void setInstantiationDependent(bool ID) {
- ExprBits.InstantiationDependent = ID;
+ return static_cast<bool>(getDependence() & ExprDependence::Instantiation);
}
/// Whether this expression contains an unexpanded parameter
@@ -221,19 +231,24 @@ public:
/// The expressions \c args and \c static_cast<Types&&>(args) both
/// contain parameter packs.
bool containsUnexpandedParameterPack() const {
- return ExprBits.ContainsUnexpandedParameterPack;
+ return static_cast<bool>(getDependence() & ExprDependence::UnexpandedPack);
}
- /// Set the bit that describes whether this expression
- /// contains an unexpanded parameter pack.
- void setContainsUnexpandedParameterPack(bool PP = true) {
- ExprBits.ContainsUnexpandedParameterPack = PP;
+ /// Whether this expression contains subexpressions which had errors, e.g. a
+ /// TypoExpr.
+ bool containsErrors() const {
+ return static_cast<bool>(getDependence() & ExprDependence::Error);
}
/// getExprLoc - Return the preferred location for the arrow when diagnosing
/// a problem with a generic expression.
SourceLocation getExprLoc() const LLVM_READONLY;
+ /// Determine whether an lvalue-to-rvalue conversion should implicitly be
+ /// applied to this expression if it appears as a discarded-value expression
+ /// in C++11 onwards. This applies to certain forms of volatile glvalues.
+ bool isReadIfDiscardedInCPlusPlus11() const;
+
/// isUnusedResultAWarning - Return true if this immediate expression should
/// be warned about if the result is unused. If so, fill in expr, location,
/// and ranges with expr to warn on and source locations/ranges appropriate
@@ -473,6 +488,11 @@ public:
/// Returns whether this expression refers to a vector element.
bool refersToVectorElement() const;
+ /// Returns whether this expression refers to a matrix element.
+ bool refersToMatrixElement() const {
+ return getObjectKind() == OK_MatrixComponent;
+ }
+
/// Returns whether this expression refers to a global register
/// variable.
bool refersToGlobalRegisterVar() const;
@@ -693,7 +713,8 @@ public:
/// Evaluate an expression that is required to be a constant expression.
bool EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage,
- const ASTContext &Ctx) const;
+ const ASTContext &Ctx,
+ bool InPlace = false) const;
/// If the current Expr is a pointer, this will try to statically
/// determine the number of bytes available where the pointer is pointing.
@@ -952,11 +973,11 @@ protected:
Stmt *SubExpr;
FullExpr(StmtClass SC, Expr *subexpr)
- : Expr(SC, subexpr->getType(),
- subexpr->getValueKind(), subexpr->getObjectKind(),
- subexpr->isTypeDependent(), subexpr->isValueDependent(),
- subexpr->isInstantiationDependent(),
- subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr) {}
+ : Expr(SC, subexpr->getType(), subexpr->getValueKind(),
+ subexpr->getObjectKind()),
+ SubExpr(subexpr) {
+ setDependence(computeDependence(this));
+ }
FullExpr(StmtClass SC, EmptyShell Empty)
: Expr(SC, Empty) {}
public:
@@ -979,11 +1000,14 @@ class ConstantExpr final
: public FullExpr,
private llvm::TrailingObjects<ConstantExpr, APValue, uint64_t> {
static_assert(std::is_same<uint64_t, llvm::APInt::WordType>::value,
- "this class assumes llvm::APInt::WordType is uint64_t for "
- "trail-allocated storage");
+ "ConstantExpr assumes that llvm::APInt::WordType is uint64_t "
+ "for tail-allocated storage");
+ friend TrailingObjects;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
public:
- /// Describes the kind of result that can be trail-allocated.
+ /// Describes the kind of result that can be tail-allocated.
enum ResultStorageKind { RSK_None, RSK_Int64, RSK_APValue };
private:
@@ -994,7 +1018,6 @@ private:
return ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64;
}
- void DefaultInit(ResultStorageKind StorageKind);
uint64_t &Int64Result() {
assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64 &&
"invalid accessor");
@@ -1008,24 +1031,22 @@ private:
"invalid accessor");
return *getTrailingObjects<APValue>();
}
- const APValue &APValueResult() const {
+ APValue &APValueResult() const {
return const_cast<ConstantExpr *>(this)->APValueResult();
}
- ConstantExpr(Expr *subexpr, ResultStorageKind StorageKind);
- ConstantExpr(ResultStorageKind StorageKind, EmptyShell Empty);
+ ConstantExpr(Expr *SubExpr, ResultStorageKind StorageKind,
+ bool IsImmediateInvocation);
+ ConstantExpr(EmptyShell Empty, ResultStorageKind StorageKind);
public:
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
static ConstantExpr *Create(const ASTContext &Context, Expr *E,
const APValue &Result);
static ConstantExpr *Create(const ASTContext &Context, Expr *E,
- ResultStorageKind Storage = RSK_None);
+ ResultStorageKind Storage = RSK_None,
+ bool IsImmediateInvocation = false);
static ConstantExpr *CreateEmpty(const ASTContext &Context,
- ResultStorageKind StorageKind,
- EmptyShell Empty);
+ ResultStorageKind StorageKind);
static ResultStorageKind getStorageKind(const APValue &Value);
static ResultStorageKind getStorageKind(const Type *T,
@@ -1053,8 +1074,14 @@ public:
ResultStorageKind getResultStorageKind() const {
return static_cast<ResultStorageKind>(ConstantExprBits.ResultKind);
}
+ bool isImmediateInvocation() const {
+ return ConstantExprBits.IsImmediateInvocation;
+ }
+ bool hasAPValueResult() const {
+ return ConstantExprBits.APValueKind != APValue::None;
+ }
APValue getAPValueResult() const;
- const APValue &getResultAsAPValue() const { return APValueResult(); }
+ APValue &getResultAsAPValue() const { return APValueResult(); }
llvm::APSInt getResultAsAPSInt() const;
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
@@ -1078,19 +1105,11 @@ class OpaqueValueExpr : public Expr {
public:
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
- ExprObjectKind OK = OK_Ordinary,
- Expr *SourceExpr = nullptr)
- : Expr(OpaqueValueExprClass, T, VK, OK,
- T->isDependentType() ||
- (SourceExpr && SourceExpr->isTypeDependent()),
- T->isDependentType() ||
- (SourceExpr && SourceExpr->isValueDependent()),
- T->isInstantiationDependentType() ||
- (SourceExpr && SourceExpr->isInstantiationDependent()),
- false),
- SourceExpr(SourceExpr) {
+ ExprObjectKind OK = OK_Ordinary, Expr *SourceExpr = nullptr)
+ : Expr(OpaqueValueExprClass, T, VK, OK), SourceExpr(SourceExpr) {
setIsUnique(false);
OpaqueValueExprBits.Loc = Loc;
+ setDependence(computeDependence(this));
}
/// Given an expression which invokes a copy constructor --- i.e. a
@@ -1210,10 +1229,6 @@ class DeclRefExpr final
/// Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {}
- /// Computes the type- and value-dependence flags for this
- /// declaration reference expression.
- void computeDependence(const ASTContext &Ctx);
-
public:
DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
bool RefersToEnclosingVariableOrCapture, QualType T,
@@ -1490,7 +1505,7 @@ class FixedPointLiteral : public Expr, public APIntStorage {
SourceLocation Loc;
unsigned Scale;
- /// \brief Construct an empty integer literal.
+ /// \brief Construct an empty fixed-point literal.
explicit FixedPointLiteral(EmptyShell Empty)
: Expr(FixedPointLiteralClass, Empty) {}
@@ -1504,6 +1519,9 @@ class FixedPointLiteral : public Expr, public APIntStorage {
QualType type, SourceLocation l,
unsigned Scale);
+ /// Returns an empty fixed-point literal.
+ static FixedPointLiteral *Create(const ASTContext &C, EmptyShell Empty);
+
SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
@@ -1512,6 +1530,9 @@ class FixedPointLiteral : public Expr, public APIntStorage {
void setLocation(SourceLocation Location) { Loc = Location; }
+ unsigned getScale() const { return Scale; }
+ void setScale(unsigned S) { Scale = S; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == FixedPointLiteralClass;
}
@@ -1544,10 +1565,10 @@ public:
// type should be IntTy
CharacterLiteral(unsigned value, CharacterKind kind, QualType type,
SourceLocation l)
- : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Value(value), Loc(l) {
+ : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary), Value(value),
+ Loc(l) {
CharacterLiteralBits.Kind = kind;
+ setDependence(ExprDependence::None);
}
/// Construct an empty character literal.
@@ -1663,9 +1684,9 @@ class ImaginaryLiteral : public Expr {
Stmt *Val;
public:
ImaginaryLiteral(Expr *val, QualType Ty)
- : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Val(val) {}
+ : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary), Val(val) {
+ setDependence(ExprDependence::None);
+ }
/// Build an empty imaginary literal.
explicit ImaginaryLiteral(EmptyShell Empty)
@@ -1902,13 +1923,17 @@ public:
/// [C99 6.4.2.2] - A predefined identifier such as __func__.
class PredefinedExpr final
: public Expr,
- private llvm::TrailingObjects<PredefinedExpr, Stmt *> {
+ private llvm::TrailingObjects<PredefinedExpr, Stmt *, Expr *,
+ TypeSourceInfo *> {
friend class ASTStmtReader;
friend TrailingObjects;
// PredefinedExpr is optionally followed by a single trailing
// "Stmt *" for the predefined identifier. It is present if and only if
// hasFunctionName() is true and is always a "StringLiteral *".
+ // It can also be followed by a Expr* in the case of a
+ // __builtin_unique_stable_name with an expression, or TypeSourceInfo * if
+ // __builtin_unique_stable_name with a type.
public:
enum IdentKind {
@@ -1921,12 +1946,18 @@ public:
PrettyFunction,
/// The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
- PrettyFunctionNoVirtual
+ PrettyFunctionNoVirtual,
+ UniqueStableNameType,
+ UniqueStableNameExpr,
};
private:
PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
StringLiteral *SL);
+ PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
+ TypeSourceInfo *Info);
+ PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
+ Expr *E);
explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName);
@@ -1939,10 +1970,39 @@ private:
*getTrailingObjects<Stmt *>() = SL;
}
+ void setTypeSourceInfo(TypeSourceInfo *Info) {
+ assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType &&
+ "TypeSourceInfo only valid for UniqueStableName of a Type");
+ *getTrailingObjects<TypeSourceInfo *>() = Info;
+ }
+
+ void setExpr(Expr *E) {
+ assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr &&
+ "TypeSourceInfo only valid for UniqueStableName of n Expression.");
+ *getTrailingObjects<Expr *>() = E;
+ }
+
+ size_t numTrailingObjects(OverloadToken<Stmt *>) const {
+ return hasFunctionName();
+ }
+
+ size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
+ return getIdentKind() == UniqueStableNameType && !hasFunctionName();
+ }
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return getIdentKind() == UniqueStableNameExpr && !hasFunctionName();
+ }
+
public:
/// Create a PredefinedExpr.
static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK, StringLiteral *SL);
+ static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
+ QualType FNTy, IdentKind IK, StringLiteral *SL,
+ TypeSourceInfo *Info);
+ static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
+ QualType FNTy, IdentKind IK, StringLiteral *SL,
+ Expr *E);
/// Create an empty PredefinedExpr.
static PredefinedExpr *CreateEmpty(const ASTContext &Ctx,
@@ -1967,8 +2027,34 @@ public:
: nullptr;
}
+ TypeSourceInfo *getTypeSourceInfo() {
+ assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType &&
+ "TypeSourceInfo only valid for UniqueStableName of a Type");
+ return *getTrailingObjects<TypeSourceInfo *>();
+ }
+
+ const TypeSourceInfo *getTypeSourceInfo() const {
+ assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType &&
+ "TypeSourceInfo only valid for UniqueStableName of a Type");
+ return *getTrailingObjects<TypeSourceInfo *>();
+ }
+
+ Expr *getExpr() {
+ assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr &&
+ "TypeSourceInfo only valid for UniqueStableName of n Expression.");
+ return *getTrailingObjects<Expr *>();
+ }
+
+ const Expr *getExpr() const {
+ assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr &&
+ "TypeSourceInfo only valid for UniqueStableName of n Expression.");
+ return *getTrailingObjects<Expr *>();
+ }
+
static StringRef getIdentKindName(IdentKind IK);
static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl);
+ static std::string ComputeName(ASTContext &Context, IdentKind IK,
+ const QualType Ty);
SourceLocation getBeginLoc() const { return getLocation(); }
SourceLocation getEndLoc() const { return getLocation(); }
@@ -1996,12 +2082,11 @@ class ParenExpr : public Expr {
Stmt *Val;
public:
ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
- : Expr(ParenExprClass, val->getType(),
- val->getValueKind(), val->getObjectKind(),
- val->isTypeDependent(), val->isValueDependent(),
- val->isInstantiationDependent(),
- val->containsUnexpandedParameterPack()),
- L(l), R(r), Val(val) {}
+ : Expr(ParenExprClass, val->getType(), val->getValueKind(),
+ val->getObjectKind()),
+ L(l), R(r), Val(val) {
+ setDependence(computeDependence(this));
+ }
/// Construct an empty parenthesized expression.
explicit ParenExpr(EmptyShell Empty)
@@ -2043,31 +2128,48 @@ public:
/// applied to a non-complex value, the former returns its operand and the
/// later returns zero in the type of the operand.
///
-class UnaryOperator : public Expr {
+class UnaryOperator final
+ : public Expr,
+ private llvm::TrailingObjects<UnaryOperator, FPOptionsOverride> {
Stmt *Val;
+ size_t numTrailingObjects(OverloadToken<FPOptionsOverride>) const {
+ return UnaryOperatorBits.HasFPFeatures ? 1 : 0;
+ }
+
+ FPOptionsOverride &getTrailingFPFeatures() {
+ assert(UnaryOperatorBits.HasFPFeatures);
+ return *getTrailingObjects<FPOptionsOverride>();
+ }
+
+ const FPOptionsOverride &getTrailingFPFeatures() const {
+ assert(UnaryOperatorBits.HasFPFeatures);
+ return *getTrailingObjects<FPOptionsOverride>();
+ }
+
public:
typedef UnaryOperatorKind Opcode;
- UnaryOperator(Expr *input, Opcode opc, QualType type, ExprValueKind VK,
- ExprObjectKind OK, SourceLocation l, bool CanOverflow)
- : Expr(UnaryOperatorClass, type, VK, OK,
- input->isTypeDependent() || type->isDependentType(),
- input->isValueDependent(),
- (input->isInstantiationDependent() ||
- type->isInstantiationDependentType()),
- input->containsUnexpandedParameterPack()),
- Val(input) {
- UnaryOperatorBits.Opc = opc;
- UnaryOperatorBits.CanOverflow = CanOverflow;
- UnaryOperatorBits.Loc = l;
- }
+protected:
+ UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc, QualType type,
+ ExprValueKind VK, ExprObjectKind OK, SourceLocation l,
+ bool CanOverflow, FPOptionsOverride FPFeatures);
/// Build an empty unary operator.
- explicit UnaryOperator(EmptyShell Empty) : Expr(UnaryOperatorClass, Empty) {
+ explicit UnaryOperator(bool HasFPFeatures, EmptyShell Empty)
+ : Expr(UnaryOperatorClass, Empty) {
UnaryOperatorBits.Opc = UO_AddrOf;
+ UnaryOperatorBits.HasFPFeatures = HasFPFeatures;
}
+public:
+ static UnaryOperator *CreateEmpty(const ASTContext &C, bool hasFPFeatures);
+
+ static UnaryOperator *Create(const ASTContext &C, Expr *input, Opcode opc,
+ QualType type, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation l,
+ bool CanOverflow, FPOptionsOverride FPFeatures);
+
Opcode getOpcode() const {
return static_cast<Opcode>(UnaryOperatorBits.Opc);
}
@@ -2089,6 +2191,18 @@ public:
bool canOverflow() const { return UnaryOperatorBits.CanOverflow; }
void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; }
+ // Get the FP contractability status of this operator. Only meaningful for
+ // operations on floating point types.
+ bool isFPContractableWithinStatement(const LangOptions &LO) const {
+ return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
+ }
+
+ // Get the FENV_ACCESS status of this operator. Only meaningful for
+ // operations on floating point types.
+ bool isFEnvAccessOn(const LangOptions &LO) const {
+ return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
+ }
+
/// isPostfix - Return true if this is a postfix operation, like x++.
static bool isPostfix(Opcode Op) {
return Op == UO_PostInc || Op == UO_PostDec;
@@ -2155,6 +2269,37 @@ public:
const_child_range children() const {
return const_child_range(&Val, &Val + 1);
}
+
+ /// Is FPFeatures in Trailing Storage?
+ bool hasStoredFPFeatures() const { return UnaryOperatorBits.HasFPFeatures; }
+
+protected:
+ /// Get FPFeatures from trailing storage
+ FPOptionsOverride getStoredFPFeatures() const {
+ return getTrailingFPFeatures();
+ }
+
+ /// Set FPFeatures in trailing storage, used only by Serialization
+ void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
+
+public:
+ // Get the FP features status of this operator. Only meaningful for
+ // operations on floating point types.
+ FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
+ if (UnaryOperatorBits.HasFPFeatures)
+ return getStoredFPFeatures().applyOverrides(LO);
+ return FPOptions::defaultWithoutTrailingStorage(LO);
+ }
+ FPOptionsOverride getFPOptionsOverride() const {
+ if (UnaryOperatorBits.HasFPFeatures)
+ return getStoredFPFeatures();
+ return FPOptionsOverride();
+ }
+
+ friend TrailingObjects;
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
};
/// Helper class for OffsetOfExpr.
@@ -2379,17 +2524,17 @@ class UnaryExprOrTypeTraitExpr : public Expr {
public:
UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo,
QualType resultType, SourceLocation op,
- SourceLocation rp) :
- Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
- false, // Never type-dependent (C++ [temp.dep.expr]p3).
- // Value-dependent if the argument is type-dependent.
- TInfo->getType()->isDependentType(),
- TInfo->getType()->isInstantiationDependentType(),
- TInfo->getType()->containsUnexpandedParameterPack()),
- OpLoc(op), RParenLoc(rp) {
+ SourceLocation rp)
+ : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary),
+ OpLoc(op), RParenLoc(rp) {
+ assert(ExprKind <= UETT_Last && "invalid enum value!");
UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
+ assert(static_cast<unsigned>(ExprKind) ==
+ UnaryExprOrTypeTraitExprBits.Kind &&
+ "UnaryExprOrTypeTraitExprBits.Kind overflow!");
UnaryExprOrTypeTraitExprBits.IsType = true;
Argument.Ty = TInfo;
+ setDependence(computeDependence(this));
}
UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E,
@@ -2403,7 +2548,12 @@ public:
UnaryExprOrTypeTrait getKind() const {
return static_cast<UnaryExprOrTypeTrait>(UnaryExprOrTypeTraitExprBits.Kind);
}
- void setKind(UnaryExprOrTypeTrait K) { UnaryExprOrTypeTraitExprBits.Kind = K;}
+ void setKind(UnaryExprOrTypeTrait K) {
+ assert(K <= UETT_Last && "invalid enum value!");
+ UnaryExprOrTypeTraitExprBits.Kind = K;
+ assert(static_cast<unsigned>(K) == UnaryExprOrTypeTraitExprBits.Kind &&
+ "UnaryExprOrTypeTraitExprBits.Kind overflow!");
+ }
bool isArgumentType() const { return UnaryExprOrTypeTraitExprBits.IsType; }
QualType getArgumentType() const {
@@ -2466,19 +2616,13 @@ class ArraySubscriptExpr : public Expr {
bool lhsIsBase() const { return getRHS()->getType()->isIntegerType(); }
public:
- ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation rbracketloc)
- : Expr(ArraySubscriptExprClass, t, VK, OK,
- lhs->isTypeDependent() || rhs->isTypeDependent(),
- lhs->isValueDependent() || rhs->isValueDependent(),
- (lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())) {
+ ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation rbracketloc)
+ : Expr(ArraySubscriptExprClass, t, VK, OK) {
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
- ArraySubscriptExprBits.RBracketLoc = rbracketloc;
+ ArrayOrMatrixSubscriptExprBits.RBracketLoc = rbracketloc;
+ setDependence(computeDependence(this));
}
/// Create an empty array subscript expression.
@@ -2514,10 +2658,10 @@ public:
SourceLocation getEndLoc() const { return getRBracketLoc(); }
SourceLocation getRBracketLoc() const {
- return ArraySubscriptExprBits.RBracketLoc;
+ return ArrayOrMatrixSubscriptExprBits.RBracketLoc;
}
void setRBracketLoc(SourceLocation L) {
- ArraySubscriptExprBits.RBracketLoc = L;
+ ArrayOrMatrixSubscriptExprBits.RBracketLoc = L;
}
SourceLocation getExprLoc() const LLVM_READONLY {
@@ -2537,6 +2681,84 @@ public:
}
};
+/// MatrixSubscriptExpr - Matrix subscript expression for the MatrixType
+/// extension.
+/// MatrixSubscriptExpr can be either incomplete (only Base and RowIdx are set
+/// so far, the type is IncompleteMatrixIdx) or complete (Base, RowIdx and
+/// ColumnIdx refer to valid expressions). Incomplete matrix expressions only
+/// exist during the initial construction of the AST.
+class MatrixSubscriptExpr : public Expr {
+ enum { BASE, ROW_IDX, COLUMN_IDX, END_EXPR };
+ Stmt *SubExprs[END_EXPR];
+
+public:
+ MatrixSubscriptExpr(Expr *Base, Expr *RowIdx, Expr *ColumnIdx, QualType T,
+ SourceLocation RBracketLoc)
+ : Expr(MatrixSubscriptExprClass, T, Base->getValueKind(),
+ OK_MatrixComponent) {
+ SubExprs[BASE] = Base;
+ SubExprs[ROW_IDX] = RowIdx;
+ SubExprs[COLUMN_IDX] = ColumnIdx;
+ ArrayOrMatrixSubscriptExprBits.RBracketLoc = RBracketLoc;
+ setDependence(computeDependence(this));
+ }
+
+ /// Create an empty matrix subscript expression.
+ explicit MatrixSubscriptExpr(EmptyShell Shell)
+ : Expr(MatrixSubscriptExprClass, Shell) {}
+
+ bool isIncomplete() const {
+ bool IsIncomplete = hasPlaceholderType(BuiltinType::IncompleteMatrixIdx);
+ assert((SubExprs[COLUMN_IDX] || IsIncomplete) &&
+ "expressions without column index must be marked as incomplete");
+ return IsIncomplete;
+ }
+ Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
+ const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
+ void setBase(Expr *E) { SubExprs[BASE] = E; }
+
+ Expr *getRowIdx() { return cast<Expr>(SubExprs[ROW_IDX]); }
+ const Expr *getRowIdx() const { return cast<Expr>(SubExprs[ROW_IDX]); }
+ void setRowIdx(Expr *E) { SubExprs[ROW_IDX] = E; }
+
+ Expr *getColumnIdx() { return cast_or_null<Expr>(SubExprs[COLUMN_IDX]); }
+ const Expr *getColumnIdx() const {
+ assert(!isIncomplete() &&
+ "cannot get the column index of an incomplete expression");
+ return cast<Expr>(SubExprs[COLUMN_IDX]);
+ }
+ void setColumnIdx(Expr *E) { SubExprs[COLUMN_IDX] = E; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getBase()->getBeginLoc();
+ }
+
+ SourceLocation getEndLoc() const { return getRBracketLoc(); }
+
+ SourceLocation getExprLoc() const LLVM_READONLY {
+ return getBase()->getExprLoc();
+ }
+
+ SourceLocation getRBracketLoc() const {
+ return ArrayOrMatrixSubscriptExprBits.RBracketLoc;
+ }
+ void setRBracketLoc(SourceLocation L) {
+ ArrayOrMatrixSubscriptExprBits.RBracketLoc = L;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == MatrixSubscriptExprClass;
+ }
+
+ // Iterators
+ child_range children() {
+ return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
+ }
+ const_child_range children() const {
+ return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
+ }
+};
+
/// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
/// CallExpr itself represents a normal function call, e.g., "f(x, 2)",
/// while its subclasses may represent alternative syntax that (semantically)
@@ -2553,8 +2775,6 @@ class CallExpr : public Expr {
/// the derived classes of CallExpr.
SourceLocation RParenLoc;
- void updateDependenciesFromArg(Expr *Arg);
-
// CallExpr store some data in trailing objects. However since CallExpr
// is used a base of other expression classes we cannot use
// llvm::TrailingObjects. Instead we manually perform the pointer arithmetic
@@ -2796,6 +3016,12 @@ public:
/// a non-value-dependent constant parameter evaluating as false.
bool isBuiltinAssumeFalse(const ASTContext &Ctx) const;
+ /// Used by Sema to implement MSVC-compatible delayed name lookup.
+ /// (Usually Exprs themselves should set dependence).
+ void markDependentForPostponedNameLookup() {
+ setDependence(getDependence() | ExprDependence::TypeValueInstantiation);
+ }
+
bool isCallToStdMove() const {
const FunctionDecl *FD = getDirectCallee();
return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
@@ -3088,13 +3314,10 @@ class CompoundLiteralExpr : public Expr {
public:
CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo,
QualType T, ExprValueKind VK, Expr *init, bool fileScope)
- : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary,
- tinfo->getType()->isDependentType(),
- init->isValueDependent(),
- (init->isInstantiationDependent() ||
- tinfo->getType()->isInstantiationDependentType()),
- init->containsUnexpandedParameterPack()),
- LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) {}
+ : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary),
+ LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) {
+ setDependence(computeDependence(this));
+ }
/// Construct an empty compound literal.
explicit CompoundLiteralExpr(EmptyShell Empty)
@@ -3160,26 +3383,13 @@ class CastExpr : public Expr {
protected:
CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
Expr *op, unsigned BasePathSize)
- : Expr(SC, ty, VK, OK_Ordinary,
- // Cast expressions are type-dependent if the type is
- // dependent (C++ [temp.dep.expr]p3).
- ty->isDependentType(),
- // Cast expressions are value-dependent if the type is
- // dependent or if the subexpression is value-dependent.
- ty->isDependentType() || (op && op->isValueDependent()),
- (ty->isInstantiationDependentType() ||
- (op && op->isInstantiationDependent())),
- // An implicit cast expression doesn't (lexically) contain an
- // unexpanded pack, even if its target type does.
- ((SC != ImplicitCastExprClass &&
- ty->containsUnexpandedParameterPack()) ||
- (op && op->containsUnexpandedParameterPack()))),
- Op(op) {
+ : Expr(SC, ty, VK, OK_Ordinary), Op(op) {
CastExprBits.Kind = kind;
CastExprBits.PartOfExplicitCast = false;
CastExprBits.BasePathSize = BasePathSize;
assert((CastExprBits.BasePathSize == BasePathSize) &&
"BasePathSize overflow!");
+ setDependence(computeDependence(this));
assert(CastConsistency());
}
@@ -3438,30 +3648,39 @@ class BinaryOperator : public Expr {
public:
typedef BinaryOperatorKind Opcode;
- BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, FPOptions FPFeatures)
- : Expr(BinaryOperatorClass, ResTy, VK, OK,
- lhs->isTypeDependent() || rhs->isTypeDependent(),
- lhs->isValueDependent() || rhs->isValueDependent(),
- (lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())) {
- BinaryOperatorBits.Opc = opc;
- BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
- BinaryOperatorBits.OpLoc = opLoc;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- assert(!isCompoundAssignmentOp() &&
- "Use CompoundAssignOperator for compound assignments");
+protected:
+ size_t offsetOfTrailingStorage() const;
+
+ /// Return a pointer to the trailing FPOptions
+ FPOptionsOverride *getTrailingFPFeatures() {
+ assert(BinaryOperatorBits.HasFPFeatures);
+ return reinterpret_cast<FPOptionsOverride *>(
+ reinterpret_cast<char *>(this) + offsetOfTrailingStorage());
+ }
+ const FPOptionsOverride *getTrailingFPFeatures() const {
+ assert(BinaryOperatorBits.HasFPFeatures);
+ return reinterpret_cast<const FPOptionsOverride *>(
+ reinterpret_cast<const char *>(this) + offsetOfTrailingStorage());
}
+ /// Build a binary operator, assuming that appropriate storage has been
+ /// allocated for the trailing objects when needed.
+ BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
+ QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation opLoc, FPOptionsOverride FPFeatures);
+
/// Construct an empty binary operator.
explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) {
BinaryOperatorBits.Opc = BO_Comma;
}
+public:
+ static BinaryOperator *CreateEmpty(const ASTContext &C, bool hasFPFeatures);
+
+ static BinaryOperator *Create(const ASTContext &C, Expr *lhs, Expr *rhs,
+ Opcode opc, QualType ResTy, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation opLoc,
+ FPOptionsOverride FPFeatures);
SourceLocation getExprLoc() const { return getOperatorLoc(); }
SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; }
void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
@@ -3602,47 +3821,65 @@ public:
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
}
- // Set the FP contractability status of this operator. Only meaningful for
+ /// Set and fetch the bit that shows whether FPFeatures needs to be
+ /// allocated in Trailing Storage
+ void setHasStoredFPFeatures(bool B) { BinaryOperatorBits.HasFPFeatures = B; }
+ bool hasStoredFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; }
+
+ /// Get FPFeatures from trailing storage
+ FPOptionsOverride getStoredFPFeatures() const {
+ assert(hasStoredFPFeatures());
+ return *getTrailingFPFeatures();
+ }
+ /// Set FPFeatures in trailing storage, used only by Serialization
+ void setStoredFPFeatures(FPOptionsOverride F) {
+ assert(BinaryOperatorBits.HasFPFeatures);
+ *getTrailingFPFeatures() = F;
+ }
+
+ // Get the FP features status of this operator. Only meaningful for
// operations on floating point types.
- void setFPFeatures(FPOptions F) {
- BinaryOperatorBits.FPFeatures = F.getInt();
+ FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
+ if (BinaryOperatorBits.HasFPFeatures)
+ return getStoredFPFeatures().applyOverrides(LO);
+ return FPOptions::defaultWithoutTrailingStorage(LO);
}
- FPOptions getFPFeatures() const {
- return FPOptions(BinaryOperatorBits.FPFeatures);
+ // This is used in ASTImporter
+ FPOptionsOverride getFPFeatures(const LangOptions &LO) const {
+ if (BinaryOperatorBits.HasFPFeatures)
+ return getStoredFPFeatures();
+ return FPOptionsOverride();
}
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
- bool isFPContractableWithinStatement() const {
- return getFPFeatures().allowFPContractWithinStatement();
+ bool isFPContractableWithinStatement(const LangOptions &LO) const {
+ return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
}
// Get the FENV_ACCESS status of this operator. Only meaningful for
// operations on floating point types.
- bool isFEnvAccessOn() const { return getFPFeatures().allowFEnvAccess(); }
+ bool isFEnvAccessOn(const LangOptions &LO) const {
+ return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
+ }
protected:
- BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, FPOptions FPFeatures, bool dead2)
- : Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
- lhs->isTypeDependent() || rhs->isTypeDependent(),
- lhs->isValueDependent() || rhs->isValueDependent(),
- (lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())) {
- BinaryOperatorBits.Opc = opc;
- BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
- BinaryOperatorBits.OpLoc = opLoc;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
+ BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
+ QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation opLoc, FPOptionsOverride FPFeatures,
+ bool dead2);
+ /// Construct an empty BinaryOperator, SC is CompoundAssignOperator.
BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
BinaryOperatorBits.Opc = BO_MulAssign;
}
+
+ /// Return the size in bytes needed for the trailing objects.
+ /// Used to allocate the right amount of storage.
+ static unsigned sizeOfTrailingObjects(bool HasFPFeatures) {
+ return HasFPFeatures * sizeof(FPOptionsOverride);
+ }
};
/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
@@ -3654,22 +3891,33 @@ protected:
class CompoundAssignOperator : public BinaryOperator {
QualType ComputationLHSType;
QualType ComputationResultType;
-public:
- CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
- ExprValueKind VK, ExprObjectKind OK,
- QualType CompLHSType, QualType CompResultType,
- SourceLocation OpLoc, FPOptions FPFeatures)
- : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
- true),
- ComputationLHSType(CompLHSType),
- ComputationResultType(CompResultType) {
+
+ /// Construct an empty CompoundAssignOperator.
+ explicit CompoundAssignOperator(const ASTContext &C, EmptyShell Empty,
+ bool hasFPFeatures)
+ : BinaryOperator(CompoundAssignOperatorClass, Empty) {}
+
+protected:
+ CompoundAssignOperator(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc,
+ QualType ResType, ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation OpLoc, FPOptionsOverride FPFeatures,
+ QualType CompLHSType, QualType CompResultType)
+ : BinaryOperator(C, lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
+ true),
+ ComputationLHSType(CompLHSType), ComputationResultType(CompResultType) {
assert(isCompoundAssignmentOp() &&
"Only should be used for compound assignments");
}
- /// Build an empty compound assignment operator expression.
- explicit CompoundAssignOperator(EmptyShell Empty)
- : BinaryOperator(CompoundAssignOperatorClass, Empty) { }
+public:
+ static CompoundAssignOperator *CreateEmpty(const ASTContext &C,
+ bool hasFPFeatures);
+
+ static CompoundAssignOperator *
+ Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+ ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
+ FPOptionsOverride FPFeatures, QualType CompLHSType = QualType(),
+ QualType CompResultType = QualType());
// The two computation types are the type the LHS is converted
// to for the computation and the type of the result; the two are
@@ -3685,6 +3933,12 @@ public:
}
};
+inline size_t BinaryOperator::offsetOfTrailingStorage() const {
+ assert(BinaryOperatorBits.HasFPFeatures);
+ return isa<CompoundAssignOperator>(this) ? sizeof(CompoundAssignOperator)
+ : sizeof(BinaryOperator);
+}
+
/// AbstractConditionalOperator - An abstract base class for
/// ConditionalOperator and BinaryConditionalOperator.
class AbstractConditionalOperator : public Expr {
@@ -3692,14 +3946,10 @@ class AbstractConditionalOperator : public Expr {
friend class ASTStmtReader;
protected:
- AbstractConditionalOperator(StmtClass SC, QualType T,
- ExprValueKind VK, ExprObjectKind OK,
- bool TD, bool VD, bool ID,
- bool ContainsUnexpandedParameterPack,
- SourceLocation qloc,
+ AbstractConditionalOperator(StmtClass SC, QualType T, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation qloc,
SourceLocation cloc)
- : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack),
- QuestionLoc(qloc), ColonLoc(cloc) {}
+ : Expr(SC, T, VK, OK), QuestionLoc(qloc), ColonLoc(cloc) {}
AbstractConditionalOperator(StmtClass SC, EmptyShell Empty)
: Expr(SC, Empty) { }
@@ -3738,26 +3988,12 @@ public:
ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs,
SourceLocation CLoc, Expr *rhs, QualType t,
ExprValueKind VK, ExprObjectKind OK)
- : AbstractConditionalOperator(
- ConditionalOperatorClass, t, VK, OK,
- // The type of the conditional operator depends on the type
- // of the conditional to support the GCC vector conditional
- // extension. Additionally, [temp.dep.expr] does specify state that
- // this should be dependent on ALL sub expressions.
- (cond->isTypeDependent() || lhs->isTypeDependent() ||
- rhs->isTypeDependent()),
- (cond->isValueDependent() || lhs->isValueDependent() ||
- rhs->isValueDependent()),
- (cond->isInstantiationDependent() ||
- lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (cond->containsUnexpandedParameterPack() ||
- lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack()),
- QLoc, CLoc) {
+ : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK, QLoc,
+ CLoc) {
SubExprs[COND] = cond;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
+ setDependence(computeDependence(this));
}
/// Build an empty conditional operator.
@@ -3822,20 +4058,15 @@ public:
Expr *cond, Expr *lhs, Expr *rhs,
SourceLocation qloc, SourceLocation cloc,
QualType t, ExprValueKind VK, ExprObjectKind OK)
- : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK,
- (common->isTypeDependent() || rhs->isTypeDependent()),
- (common->isValueDependent() || rhs->isValueDependent()),
- (common->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (common->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack()),
- qloc, cloc),
- OpaqueValue(opaqueValue) {
+ : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK,
+ qloc, cloc),
+ OpaqueValue(opaqueValue) {
SubExprs[COMMON] = common;
SubExprs[COND] = cond;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
assert(OpaqueValue->getSourceExpr() == common && "Wrong opaque value");
+ setDependence(computeDependence(this));
}
/// Build an empty conditional operator.
@@ -3913,9 +4144,10 @@ class AddrLabelExpr : public Expr {
public:
AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L,
QualType t)
- : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false,
- false),
- AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
+ : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary), AmpAmpLoc(AALoc),
+ LabelLoc(LLoc), Label(L) {
+ setDependence(ExprDependence::None);
+ }
/// Build an empty address of a label expression.
explicit AddrLabelExpr(EmptyShell Empty)
@@ -3955,14 +4187,15 @@ class StmtExpr : public Expr {
Stmt *SubStmt;
SourceLocation LParenLoc, RParenLoc;
public:
- // FIXME: Does type-dependence need to be computed differently?
- // FIXME: Do we need to compute instantiation instantiation-dependence for
- // statements? (ugh!)
- StmtExpr(CompoundStmt *substmt, QualType T,
- SourceLocation lp, SourceLocation rp) :
- Expr(StmtExprClass, T, VK_RValue, OK_Ordinary,
- T->isDependentType(), false, false, false),
- SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
+ StmtExpr(CompoundStmt *SubStmt, QualType T, SourceLocation LParenLoc,
+ SourceLocation RParenLoc, unsigned TemplateDepth)
+ : Expr(StmtExprClass, T, VK_RValue, OK_Ordinary), SubStmt(SubStmt),
+ LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
+ setDependence(computeDependence(this, TemplateDepth));
+ // FIXME: A templated statement expression should have an associated
+ // DeclContext so that nested declarations always have a dependent context.
+ StmtExprBits.TemplateDepth = TemplateDepth;
+ }
/// Build an empty statement expression.
explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { }
@@ -3979,6 +4212,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+ unsigned getTemplateDepth() const { return StmtExprBits.TemplateDepth; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == StmtExprClass;
}
@@ -4075,17 +4310,13 @@ private:
explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {}
public:
- ConvertVectorExpr(Expr* SrcExpr, TypeSourceInfo *TI, QualType DstType,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation BuiltinLoc, SourceLocation RParenLoc)
- : Expr(ConvertVectorExprClass, DstType, VK, OK,
- DstType->isDependentType(),
- DstType->isDependentType() || SrcExpr->isValueDependent(),
- (DstType->isInstantiationDependentType() ||
- SrcExpr->isInstantiationDependent()),
- (DstType->containsUnexpandedParameterPack() ||
- SrcExpr->containsUnexpandedParameterPack())),
- SrcExpr(SrcExpr), TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
+ ConvertVectorExpr(Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType,
+ ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation BuiltinLoc, SourceLocation RParenLoc)
+ : Expr(ConvertVectorExprClass, DstType, VK, OK), SrcExpr(SrcExpr),
+ TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {
+ setDependence(computeDependence(this));
+ }
/// getSrcExpr - Return the Expr to be converted.
Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
@@ -4133,22 +4364,17 @@ class ChooseExpr : public Expr {
SourceLocation BuiltinLoc, RParenLoc;
bool CondIsTrue;
public:
- ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs,
- QualType t, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation RP, bool condIsTrue,
- bool TypeDependent, bool ValueDependent)
- : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent,
- (cond->isInstantiationDependent() ||
- lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (cond->containsUnexpandedParameterPack() ||
- lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- BuiltinLoc(BLoc), RParenLoc(RP), CondIsTrue(condIsTrue) {
- SubExprs[COND] = cond;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
+ ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t,
+ ExprValueKind VK, ExprObjectKind OK, SourceLocation RP,
+ bool condIsTrue)
+ : Expr(ChooseExprClass, t, VK, OK), BuiltinLoc(BLoc), RParenLoc(RP),
+ CondIsTrue(condIsTrue) {
+ SubExprs[COND] = cond;
+ SubExprs[LHS] = lhs;
+ SubExprs[RHS] = rhs;
+
+ setDependence(computeDependence(this));
+ }
/// Build an empty __builtin_choose_expr.
explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) { }
@@ -4213,9 +4439,9 @@ class GNUNullExpr : public Expr {
public:
GNUNullExpr(QualType Ty, SourceLocation Loc)
- : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false,
- false),
- TokenLoc(Loc) { }
+ : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary), TokenLoc(Loc) {
+ setDependence(ExprDependence::None);
+ }
/// Build an empty GNU __null expression.
explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { }
@@ -4248,12 +4474,10 @@ class VAArgExpr : public Expr {
public:
VAArgExpr(SourceLocation BLoc, Expr *e, TypeSourceInfo *TInfo,
SourceLocation RPLoc, QualType t, bool IsMS)
- : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, t->isDependentType(),
- false, (TInfo->getType()->isInstantiationDependentType() ||
- e->isInstantiationDependent()),
- (TInfo->getType()->containsUnexpandedParameterPack() ||
- e->containsUnexpandedParameterPack())),
- Val(e), TInfo(TInfo, IsMS), BuiltinLoc(BLoc), RParenLoc(RPLoc) {}
+ : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary), Val(e),
+ TInfo(TInfo, IsMS), BuiltinLoc(BLoc), RParenLoc(RPLoc) {
+ setDependence(computeDependence(this));
+ }
/// Create an empty __builtin_va_arg expression.
explicit VAArgExpr(EmptyShell Empty)
@@ -4462,13 +4686,8 @@ public:
assert(Init < getNumInits() && "Initializer access out of range!");
InitExprs[Init] = expr;
- if (expr) {
- ExprBits.TypeDependent |= expr->isTypeDependent();
- ExprBits.ValueDependent |= expr->isValueDependent();
- ExprBits.InstantiationDependent |= expr->isInstantiationDependent();
- ExprBits.ContainsUnexpandedParameterPack |=
- expr->containsUnexpandedParameterPack();
- }
+ if (expr)
+ setDependence(getDependence() | expr->getDependence());
}
/// Reserve space for some number of initializers.
@@ -4937,8 +5156,9 @@ public:
class NoInitExpr : public Expr {
public:
explicit NoInitExpr(QualType ty)
- : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary,
- false, false, ty->isInstantiationDependentType(), false) { }
+ : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary) {
+ setDependence(computeDependence(this));
+ }
explicit NoInitExpr(EmptyShell Empty)
: Expr(NoInitExprClass, Empty) { }
@@ -5032,12 +5252,10 @@ class ArrayInitLoopExpr : public Expr {
public:
explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr *ElementInit)
- : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary, false,
- CommonInit->isValueDependent() || ElementInit->isValueDependent(),
- T->isInstantiationDependentType(),
- CommonInit->containsUnexpandedParameterPack() ||
- ElementInit->containsUnexpandedParameterPack()),
- SubExprs{CommonInit, ElementInit} {}
+ : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary),
+ SubExprs{CommonInit, ElementInit} {
+ setDependence(computeDependence(this));
+ }
/// Get the common subexpression shared by all initializations (the source
/// array).
@@ -5085,8 +5303,9 @@ class ArrayInitIndexExpr : public Expr {
public:
explicit ArrayInitIndexExpr(QualType T)
- : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary,
- false, false, false, false) {}
+ : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary) {
+ setDependence(ExprDependence::None);
+ }
static bool classof(const Stmt *S) {
return S->getStmtClass() == ArrayInitIndexExprClass;
@@ -5117,8 +5336,9 @@ public:
class ImplicitValueInitExpr : public Expr {
public:
explicit ImplicitValueInitExpr(QualType ty)
- : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary,
- false, false, ty->isInstantiationDependentType(), false) { }
+ : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary) {
+ setDependence(computeDependence(this));
+ }
/// Construct an empty implicit value initialization.
explicit ImplicitValueInitExpr(EmptyShell Empty)
@@ -5277,10 +5497,9 @@ class GenericSelectionExpr final
template <bool Const> class AssociationTy {
friend class GenericSelectionExpr;
template <bool OtherConst> friend class AssociationIteratorTy;
- using ExprPtrTy =
- typename std::conditional<Const, const Expr *, Expr *>::type;
- using TSIPtrTy = typename std::conditional<Const, const TypeSourceInfo *,
- TypeSourceInfo *>::type;
+ using ExprPtrTy = std::conditional_t<Const, const Expr *, Expr *>;
+ using TSIPtrTy =
+ std::conditional_t<Const, const TypeSourceInfo *, TypeSourceInfo *>;
ExprPtrTy E;
TSIPtrTy TSI;
bool Selected;
@@ -5322,10 +5541,9 @@ class GenericSelectionExpr final
// const Association &Assoc = *It++; // Oops, Assoc is dangling.
using BaseTy = typename AssociationIteratorTy::iterator_facade_base;
using StmtPtrPtrTy =
- typename std::conditional<Const, const Stmt *const *, Stmt **>::type;
- using TSIPtrPtrTy =
- typename std::conditional<Const, const TypeSourceInfo *const *,
- TypeSourceInfo **>::type;
+ std::conditional_t<Const, const Stmt *const *, Stmt **>;
+ using TSIPtrPtrTy = std::conditional_t<Const, const TypeSourceInfo *const *,
+ TypeSourceInfo **>;
StmtPtrPtrTy E; // = nullptr; FIXME: Once support for gcc 4.8 is dropped.
TSIPtrPtrTy TSI; // Kept in sync with E.
unsigned Offset = 0, SelectedOffset = 0;
@@ -5522,12 +5740,11 @@ class ExtVectorElementExpr : public Expr {
public:
ExtVectorElementExpr(QualType ty, ExprValueKind VK, Expr *base,
IdentifierInfo &accessor, SourceLocation loc)
- : Expr(ExtVectorElementExprClass, ty, VK,
- (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent),
- base->isTypeDependent(), base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- Base(base), Accessor(&accessor), AccessorLoc(loc) {}
+ : Expr(ExtVectorElementExprClass, ty, VK,
+ (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent)),
+ Base(base), Accessor(&accessor), AccessorLoc(loc) {
+ setDependence(computeDependence(this));
+ }
/// Build an empty vector element expression.
explicit ExtVectorElementExpr(EmptyShell Empty)
@@ -5581,11 +5798,9 @@ protected:
BlockDecl *TheBlock;
public:
BlockExpr(BlockDecl *BD, QualType ty)
- : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary,
- ty->isDependentType(), ty->isDependentType(),
- ty->isInstantiationDependentType() || BD->isDependentContext(),
- false),
- TheBlock(BD) {}
+ : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary), TheBlock(BD) {
+ setDependence(computeDependence(this));
+ }
/// Build an empty block expression.
explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { }
@@ -5649,17 +5864,13 @@ private:
explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {}
public:
- AsTypeExpr(Expr* SrcExpr, QualType DstType,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation BuiltinLoc, SourceLocation RParenLoc)
- : Expr(AsTypeExprClass, DstType, VK, OK,
- DstType->isDependentType(),
- DstType->isDependentType() || SrcExpr->isValueDependent(),
- (DstType->isInstantiationDependentType() ||
- SrcExpr->isInstantiationDependent()),
- (DstType->containsUnexpandedParameterPack() ||
- SrcExpr->containsUnexpandedParameterPack())),
- SrcExpr(SrcExpr), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
+ AsTypeExpr(Expr *SrcExpr, QualType DstType, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation BuiltinLoc,
+ SourceLocation RParenLoc)
+ : Expr(AsTypeExprClass, DstType, VK, OK), SrcExpr(SrcExpr),
+ BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {
+ setDependence(computeDependence(this));
+ }
/// getSrcExpr - Return the Expr to be converted.
Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
@@ -5976,14 +6187,15 @@ public:
/// TypoExpr - Internal placeholder for expressions where typo correction
/// still needs to be performed and/or an error diagnostic emitted.
class TypoExpr : public Expr {
+ // The location for the typo name.
+ SourceLocation TypoLoc;
+
public:
- TypoExpr(QualType T)
- : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary,
- /*isTypeDependent*/ true,
- /*isValueDependent*/ true,
- /*isInstantiationDependent*/ true,
- /*containsUnexpandedParameterPack*/ false) {
+ TypoExpr(QualType T, SourceLocation TypoLoc)
+ : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary), TypoLoc(TypoLoc) {
assert(T->isDependentType() && "TypoExpr given a non-dependent type");
+ setDependence(ExprDependence::TypeValueInstantiation |
+ ExprDependence::Error);
}
child_range children() {
@@ -5993,14 +6205,88 @@ public:
return const_child_range(const_child_iterator(), const_child_iterator());
}
- SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return TypoLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return TypoLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == TypoExprClass;
}
};
+
+/// Frontend produces RecoveryExprs on semantic errors that prevent creating
+/// other well-formed expressions. E.g. when type-checking of a binary operator
+/// fails, we cannot produce a BinaryOperator expression. Instead, we can choose
+/// to produce a recovery expression storing left and right operands.
+///
+/// RecoveryExpr does not have any semantic meaning in C++, it is only useful to
+/// preserve expressions in AST that would otherwise be dropped. It captures
+/// subexpressions of some expression that we could not construct and source
+/// range covered by the expression.
+///
+/// By default, RecoveryExpr uses dependence-bits to take advantage of existing
+/// machinery to deal with dependent code in C++, e.g. RecoveryExpr is preserved
+/// in `decltype(<broken-expr>)` as part of the `DependentDecltypeType`. In
+/// addition to that, clang does not report most errors on dependent
+/// expressions, so we get rid of bogus errors for free. However, note that
+/// unlike other dependent expressions, RecoveryExpr can be produced in
+/// non-template contexts.
+///
+/// We will preserve the type in RecoveryExpr when the type is known, e.g.
+/// preserving the return type for a broken non-overloaded function call, a
+/// overloaded call where all candidates have the same return type. In this
+/// case, the expression is not type-dependent (unless the known type is itself
+/// dependent)
+///
+/// One can also reliably suppress all bogus errors on expressions containing
+/// recovery expressions by examining results of Expr::containsErrors().
+///
+/// FIXME: RecoveryExpr is currently generated by default in C++ mode only, as
+/// dependence isn't handled properly on several C-only codepaths.
+class RecoveryExpr final : public Expr,
+ private llvm::TrailingObjects<RecoveryExpr, Expr *> {
+public:
+ static RecoveryExpr *Create(ASTContext &Ctx, QualType T,
+ SourceLocation BeginLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> SubExprs);
+ static RecoveryExpr *CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs);
+
+ ArrayRef<Expr *> subExpressions() {
+ auto *B = getTrailingObjects<Expr *>();
+ return llvm::makeArrayRef(B, B + NumExprs);
+ }
+
+ ArrayRef<const Expr *> subExpressions() const {
+ return const_cast<RecoveryExpr *>(this)->subExpressions();
+ }
+
+ child_range children() {
+ Stmt **B = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
+ return child_range(B, B + NumExprs);
+ }
+
+ SourceLocation getBeginLoc() const { return BeginLoc; }
+ SourceLocation getEndLoc() const { return EndLoc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == RecoveryExprClass;
+ }
+
+private:
+ RecoveryExpr(ASTContext &Ctx, QualType T, SourceLocation BeginLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> SubExprs);
+ RecoveryExpr(EmptyShell Empty, unsigned NumSubExprs)
+ : Expr(RecoveryExprClass, Empty), NumExprs(NumSubExprs) {}
+
+ size_t numTrailingObjects(OverloadToken<Stmt *>) const { return NumExprs; }
+
+ SourceLocation BeginLoc, EndLoc;
+ unsigned NumExprs;
+ friend TrailingObjects;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+};
+
} // end namespace clang
#endif // LLVM_CLANG_AST_EXPR_H
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 2c29409e0ca5..6f0b68479b9d 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -15,15 +15,18 @@
#define LLVM_CLANG_AST_EXPRCXX_H
#include "clang/AST/ASTConcept.h"
+#include "clang/AST/ComputeDependence.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DependenceFlags.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h"
@@ -81,6 +84,7 @@ class CXXOperatorCallExpr final : public CallExpr {
friend class ASTStmtWriter;
SourceRange Range;
+ FPOptionsOverride Overrides;
// CXXOperatorCallExpr has some trailing objects belonging
// to CallExpr. See CallExpr for the details.
@@ -89,7 +93,7 @@ class CXXOperatorCallExpr final : public CallExpr {
CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation OperatorLoc, FPOptions FPFeatures,
+ SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
ADLCallKind UsesADL);
CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty);
@@ -98,7 +102,7 @@ public:
static CXXOperatorCallExpr *
Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation OperatorLoc, FPOptions FPFeatures,
+ SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
ADLCallKind UsesADL = NotADL);
static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
@@ -119,6 +123,22 @@ public:
}
bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
+ static bool isComparisonOp(OverloadedOperatorKind Opc) {
+ switch (Opc) {
+ case OO_EqualEqual:
+ case OO_ExclaimEqual:
+ case OO_Greater:
+ case OO_GreaterEqual:
+ case OO_Less:
+ case OO_LessEqual:
+ case OO_Spaceship:
+ return true;
+ default:
+ return false;
+ }
+ }
+ bool isComparisonOp() const { return isComparisonOp(getOperator()); }
+
/// Is this written as an infix binary operator?
bool isInfixBinaryOp() const;
@@ -145,20 +165,10 @@ public:
return T->getStmtClass() == CXXOperatorCallExprClass;
}
- // Set the FP contractability status of this operator. Only meaningful for
+ // Set the FPFeatures status of this operator. Only meaningful for
// operations on floating point types.
- void setFPFeatures(FPOptions F) {
- CXXOperatorCallExprBits.FPFeatures = F.getInt();
- }
- FPOptions getFPFeatures() const {
- return FPOptions(CXXOperatorCallExprBits.FPFeatures);
- }
-
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- bool isFPContractableWithinStatement() const {
- return getFPFeatures().allowFPContractWithinStatement();
- }
+ void setFPFeatures(FPOptionsOverride F) { Overrides = F; }
+ FPOptionsOverride getFPFeatures() const { return Overrides; }
};
/// Represents a call to a member function that
@@ -280,12 +290,10 @@ class CXXRewrittenBinaryOperator : public Expr {
public:
CXXRewrittenBinaryOperator(Expr *SemanticForm, bool IsReversed)
: Expr(CXXRewrittenBinaryOperatorClass, SemanticForm->getType(),
- SemanticForm->getValueKind(), SemanticForm->getObjectKind(),
- SemanticForm->isTypeDependent(), SemanticForm->isValueDependent(),
- SemanticForm->isInstantiationDependent(),
- SemanticForm->containsUnexpandedParameterPack()),
+ SemanticForm->getValueKind(), SemanticForm->getObjectKind()),
SemanticForm(SemanticForm) {
CXXRewrittenBinaryOperatorBits.IsReversed = IsReversed;
+ setDependence(computeDependence(this));
}
CXXRewrittenBinaryOperator(EmptyShell Empty)
: Expr(CXXRewrittenBinaryOperatorClass, Empty), SemanticForm() {}
@@ -350,7 +358,8 @@ public:
/// This abstract class is inherited by all of the classes
/// representing "named" casts: CXXStaticCastExpr for \c static_cast,
/// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for
-/// reinterpret_cast, and CXXConstCastExpr for \c const_cast.
+/// reinterpret_cast, CXXConstCastExpr for \c const_cast and
+/// CXXAddrspaceCastExpr for addrspace_cast (in OpenCL).
class CXXNamedCastExpr : public ExplicitCastExpr {
private:
// the location of the casting op
@@ -396,6 +405,7 @@ public:
case CXXDynamicCastExprClass:
case CXXReinterpretCastExprClass:
case CXXConstCastExprClass:
+ case CXXAddrspaceCastExprClass:
return true;
default:
return false;
@@ -553,6 +563,41 @@ public:
}
};
+/// A C++ addrspace_cast expression (currently only enabled for OpenCL).
+///
+/// This expression node represents a cast between pointers to objects in
+/// different address spaces e.g.,
+/// \c addrspace_cast<global int*>(PtrToGenericInt).
+///
+/// A addrspace_cast can cast address space type qualifiers but does not change
+/// the underlying value.
+class CXXAddrspaceCastExpr final
+ : public CXXNamedCastExpr,
+ private llvm::TrailingObjects<CXXAddrspaceCastExpr, CXXBaseSpecifier *> {
+ CXXAddrspaceCastExpr(QualType ty, ExprValueKind VK, CastKind Kind, Expr *op,
+ TypeSourceInfo *writtenTy, SourceLocation l,
+ SourceLocation RParenLoc, SourceRange AngleBrackets)
+ : CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0,
+ writtenTy, l, RParenLoc, AngleBrackets) {}
+
+ explicit CXXAddrspaceCastExpr(EmptyShell Empty)
+ : CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0) {}
+
+public:
+ friend class CastExpr;
+ friend TrailingObjects;
+
+ static CXXAddrspaceCastExpr *
+ Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind,
+ Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L,
+ SourceLocation RParenLoc, SourceRange AngleBrackets);
+ static CXXAddrspaceCastExpr *CreateEmpty(const ASTContext &Context);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXAddrspaceCastExprClass;
+ }
+};
+
/// A call to a literal operator (C++11 [over.literal])
/// written as a user-defined literal (C++11 [lit.ext]).
///
@@ -646,10 +691,10 @@ public:
class CXXBoolLiteralExpr : public Expr {
public:
CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc)
- : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false) {
+ : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary) {
CXXBoolLiteralExprBits.Value = Val;
CXXBoolLiteralExprBits.Loc = Loc;
+ setDependence(ExprDependence::None);
}
explicit CXXBoolLiteralExpr(EmptyShell Empty)
@@ -684,9 +729,9 @@ public:
class CXXNullPtrLiteralExpr : public Expr {
public:
CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc)
- : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false,
- false, false, false) {
+ : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary) {
CXXNullPtrLiteralExprBits.Loc = Loc;
+ setDependence(ExprDependence::None);
}
explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
@@ -724,11 +769,10 @@ public:
friend class ASTStmtReader;
CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
- : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary,
- Ty->isDependentType(), SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- SubExpr(SubExpr) {}
+ : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary),
+ SubExpr(SubExpr) {
+ setDependence(computeDependence(this));
+ }
Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }
@@ -763,32 +807,24 @@ public:
///
/// This represents code like \c typeid(int) or \c typeid(*objPtr)
class CXXTypeidExpr : public Expr {
+ friend class ASTStmtReader;
+
private:
llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
SourceRange Range;
public:
CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- false,
- // typeid is value-dependent if the type or expression are
- // dependent
- Operand->getType()->isDependentType(),
- Operand->getType()->isInstantiationDependentType(),
- Operand->getType()->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) {}
+ : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
+ Range(R) {
+ setDependence(computeDependence(this));
+ }
CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- false,
- // typeid is value-dependent if the type or expression are
- // dependent
- Operand->isTypeDependent() || Operand->isValueDependent(),
- Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) {}
+ : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
+ Range(R) {
+ setDependence(computeDependence(this));
+ }
CXXTypeidExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXTypeidExprClass, Empty) {
@@ -813,22 +849,11 @@ public:
assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
return Operand.get<TypeSourceInfo *>();
}
-
- void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
- assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
- Operand = TSI;
- }
-
Expr *getExprOperand() const {
assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
return static_cast<Expr*>(Operand.get<Stmt *>());
}
- void setExprOperand(Expr *E) {
- assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
- Operand = E;
- }
-
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
@@ -873,15 +898,12 @@ public:
MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
QualType ty, ExprValueKind VK,
- NestedNameSpecifierLoc qualifierLoc,
- SourceLocation nameLoc)
- : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary,
- /*type-dependent*/ false, baseExpr->isValueDependent(),
- baseExpr->isInstantiationDependent(),
- baseExpr->containsUnexpandedParameterPack()),
- BaseExpr(baseExpr), TheDecl(decl),
- MemberLoc(nameLoc), IsArrow(isArrow),
- QualifierLoc(qualifierLoc) {}
+ NestedNameSpecifierLoc qualifierLoc, SourceLocation nameLoc)
+ : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary), BaseExpr(baseExpr),
+ TheDecl(decl), MemberLoc(nameLoc), IsArrow(isArrow),
+ QualifierLoc(qualifierLoc) {
+ setDependence(computeDependence(this));
+ }
MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
@@ -949,12 +971,11 @@ class MSPropertySubscriptExpr : public Expr {
public:
MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK,
ExprObjectKind OK, SourceLocation RBracketLoc)
- : Expr(MSPropertySubscriptExprClass, Ty, VK, OK, Idx->isTypeDependent(),
- Idx->isValueDependent(), Idx->isInstantiationDependent(),
- Idx->containsUnexpandedParameterPack()),
+ : Expr(MSPropertySubscriptExprClass, Ty, VK, OK),
RBracketLoc(RBracketLoc) {
SubExprs[BASE_EXPR] = Base;
SubExprs[IDX_EXPR] = Idx;
+ setDependence(computeDependence(this));
}
/// Create an empty array subscript expression.
@@ -999,25 +1020,26 @@ public:
///
/// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr)
class CXXUuidofExpr : public Expr {
+ friend class ASTStmtReader;
+
private:
llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
- StringRef UuidStr;
+ MSGuidDecl *Guid;
SourceRange Range;
public:
- CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, StringRef UuidStr,
+ CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, MSGuidDecl *Guid,
SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false,
- Operand->getType()->isDependentType(),
- Operand->getType()->isInstantiationDependentType(),
- Operand->getType()->containsUnexpandedParameterPack()),
- Operand(Operand), UuidStr(UuidStr), Range(R) {}
-
- CXXUuidofExpr(QualType Ty, Expr *Operand, StringRef UuidStr, SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false,
- Operand->isTypeDependent(), Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Operand(Operand), UuidStr(UuidStr), Range(R) {}
+ : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
+ Guid(Guid), Range(R) {
+ setDependence(computeDependence(this));
+ }
+
+ CXXUuidofExpr(QualType Ty, Expr *Operand, MSGuidDecl *Guid, SourceRange R)
+ : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
+ Guid(Guid), Range(R) {
+ setDependence(computeDependence(this));
+ }
CXXUuidofExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXUuidofExprClass, Empty) {
@@ -1038,24 +1060,12 @@ public:
assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
return Operand.get<TypeSourceInfo *>();
}
-
- void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
- assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
- Operand = TSI;
- }
-
Expr *getExprOperand() const {
assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
return static_cast<Expr*>(Operand.get<Stmt *>());
}
- void setExprOperand(Expr *E) {
- assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
- Operand = E;
- }
-
- void setUuidStr(StringRef US) { UuidStr = US; }
- StringRef getUuidStr() const { return UuidStr; }
+ MSGuidDecl *getGuidDecl() const { return Guid; }
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
@@ -1098,14 +1108,10 @@ public:
class CXXThisExpr : public Expr {
public:
CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit)
- : Expr(CXXThisExprClass, Ty, VK_RValue, OK_Ordinary,
- // 'this' is type-dependent if the class type of the enclosing
- // member function is dependent (C++ [temp.dep.expr]p2)
- Ty->isDependentType(), Ty->isDependentType(),
- Ty->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false) {
+ : Expr(CXXThisExprClass, Ty, VK_RValue, OK_Ordinary) {
CXXThisExprBits.IsImplicit = IsImplicit;
CXXThisExprBits.Loc = L;
+ setDependence(computeDependence(this));
}
CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
@@ -1151,12 +1157,10 @@ public:
// null if not present.
CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc,
bool IsThrownVariableInScope)
- : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- Operand && Operand->isInstantiationDependent(),
- Operand && Operand->containsUnexpandedParameterPack()),
- Operand(Operand) {
+ : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary), Operand(Operand) {
CXXThrowExprBits.ThrowLoc = Loc;
CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope;
+ setDependence(computeDependence(this));
}
CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
@@ -1210,16 +1214,16 @@ class CXXDefaultArgExpr final : public Expr {
DeclContext *UsedContext;
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param,
- DeclContext *UsedContext)
+ DeclContext *UsedContext)
: Expr(SC,
Param->hasUnparsedDefaultArg()
? Param->getType().getNonReferenceType()
: Param->getDefaultArg()->getType(),
Param->getDefaultArg()->getValueKind(),
- Param->getDefaultArg()->getObjectKind(), false, false, false,
- false),
+ Param->getDefaultArg()->getObjectKind()),
Param(Param), UsedContext(UsedContext) {
CXXDefaultArgExprBits.Loc = Loc;
+ setDependence(ExprDependence::None);
}
public:
@@ -1375,13 +1379,12 @@ class CXXBindTemporaryExpr : public Expr {
CXXTemporary *Temp = nullptr;
Stmt *SubExpr = nullptr;
- CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr)
- : Expr(CXXBindTemporaryExprClass, SubExpr->getType(),
- VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(),
- SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- Temp(temp), SubExpr(SubExpr) {}
+ CXXBindTemporaryExpr(CXXTemporary *temp, Expr *SubExpr)
+ : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), VK_RValue,
+ OK_Ordinary),
+ Temp(temp), SubExpr(SubExpr) {
+ setDependence(computeDependence(this));
+ }
public:
CXXBindTemporaryExpr(EmptyShell Empty)
@@ -1632,12 +1635,12 @@ public:
CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T,
CXXConstructorDecl *Ctor, bool ConstructsVirtualBase,
bool InheritedFromVirtualBase)
- : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary, false,
- false, false, false),
+ : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary),
Constructor(Ctor), Loc(Loc),
ConstructsVirtualBase(ConstructsVirtualBase),
InheritedFromVirtualBase(InheritedFromVirtualBase) {
assert(!T->isDependentType());
+ setDependence(ExprDependence::None);
}
/// Construct an empty C++ inheriting construction expression.
@@ -1818,26 +1821,14 @@ Stmt **CXXConstructExpr::getTrailingArgs() {
/// and which can never occur implicitly.
class LambdaExpr final : public Expr,
private llvm::TrailingObjects<LambdaExpr, Stmt *> {
+ // LambdaExpr has some data stored in LambdaExprBits.
+
/// The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
/// The source location of this lambda's capture-default ('=' or '&').
SourceLocation CaptureDefaultLoc;
- /// The number of captures.
- unsigned NumCaptures : 16;
-
- /// The default capture kind, which is a value of type
- /// LambdaCaptureDefault.
- unsigned CaptureDefault : 2;
-
- /// Whether this lambda had an explicit parameter list vs. an
- /// implicit (and empty) parameter list.
- unsigned ExplicitParams : 1;
-
- /// Whether this lambda had the result type explicitly specified.
- unsigned ExplicitResultType : 1;
-
/// The location of the closing brace ('}') that completes
/// the lambda.
///
@@ -1851,23 +1842,18 @@ class LambdaExpr final : public Expr,
/// Construct a lambda expression.
LambdaExpr(QualType T, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
- SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
- bool ExplicitParams, bool ExplicitResultType,
- ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace,
- bool ContainsUnexpandedParameterPack);
+ SourceLocation CaptureDefaultLoc, bool ExplicitParams,
+ bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
+ SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
/// Construct an empty lambda expression.
- LambdaExpr(EmptyShell Empty, unsigned NumCaptures)
- : Expr(LambdaExprClass, Empty), NumCaptures(NumCaptures),
- CaptureDefault(LCD_None), ExplicitParams(false),
- ExplicitResultType(false) {
- getStoredStmts()[NumCaptures] = nullptr;
- }
+ LambdaExpr(EmptyShell Empty, unsigned NumCaptures);
Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
-
Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
+ void initBodyIfNeeded() const;
+
public:
friend class ASTStmtReader;
friend class ASTStmtWriter;
@@ -1877,9 +1863,9 @@ public:
static LambdaExpr *
Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
- ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
- bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
- SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
+ bool ExplicitParams, bool ExplicitResultType,
+ ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace,
+ bool ContainsUnexpandedParameterPack);
/// Construct a new lambda expression that will be deserialized from
/// an external source.
@@ -1888,13 +1874,11 @@ public:
/// Determine the default capture kind for this lambda.
LambdaCaptureDefault getCaptureDefault() const {
- return static_cast<LambdaCaptureDefault>(CaptureDefault);
+ return static_cast<LambdaCaptureDefault>(LambdaExprBits.CaptureDefault);
}
/// Retrieve the location of this lambda's capture-default, if any.
- SourceLocation getCaptureDefaultLoc() const {
- return CaptureDefaultLoc;
- }
+ SourceLocation getCaptureDefaultLoc() const { return CaptureDefaultLoc; }
/// Determine whether one of this lambda's captures is an init-capture.
bool isInitCapture(const LambdaCapture *Capture) const;
@@ -1917,7 +1901,7 @@ public:
capture_iterator capture_end() const;
/// Determine the number of captures in this lambda.
- unsigned capture_size() const { return NumCaptures; }
+ unsigned capture_size() const { return LambdaExprBits.NumCaptures; }
/// Retrieve this lambda's explicit captures.
capture_range explicit_captures() const;
@@ -1947,6 +1931,7 @@ public:
/// Const iterator that walks over the capture initialization
/// arguments.
+ /// FIXME: This interface is prone to being used incorrectly.
using const_capture_init_iterator = Expr *const *;
/// Retrieve the initialization expressions for this lambda's captures.
@@ -1974,13 +1959,13 @@ public:
/// Retrieve the iterator pointing one past the last
/// initialization argument for this lambda expression.
capture_init_iterator capture_init_end() {
- return capture_init_begin() + NumCaptures;
+ return capture_init_begin() + capture_size();
}
/// Retrieve the iterator pointing one past the last
/// initialization argument for this lambda expression.
const_capture_init_iterator capture_init_end() const {
- return capture_init_begin() + NumCaptures;
+ return capture_init_begin() + capture_size();
}
/// Retrieve the source range covering the lambda introducer,
@@ -2014,8 +1999,20 @@ public:
/// Whether this is a generic lambda.
bool isGenericLambda() const { return getTemplateParameterList(); }
- /// Retrieve the body of the lambda.
- CompoundStmt *getBody() const;
+ /// Retrieve the body of the lambda. This will be most of the time
+ /// a \p CompoundStmt, but can also be \p CoroutineBodyStmt wrapping
+ /// a \p CompoundStmt. Note that unlike functions, lambda-expressions
+ /// cannot have a function-try-block.
+ Stmt *getBody() const;
+
+ /// Retrieve the \p CompoundStmt representing the body of the lambda.
+ /// This is a convenience function for callers who do not need
+ /// to handle node(s) which may wrap a \p CompoundStmt.
+ const CompoundStmt *getCompoundStmtBody() const;
+ CompoundStmt *getCompoundStmtBody() {
+ const auto *ConstThis = this;
+ return const_cast<CompoundStmt *>(ConstThis->getCompoundStmtBody());
+ }
/// Determine whether the lambda is mutable, meaning that any
/// captures values can be modified.
@@ -2023,10 +2020,12 @@ public:
/// Determine whether this lambda has an explicit parameter
/// list vs. an implicit (empty) parameter list.
- bool hasExplicitParameters() const { return ExplicitParams; }
+ bool hasExplicitParameters() const { return LambdaExprBits.ExplicitParams; }
/// Whether this lambda had its result type explicitly specified.
- bool hasExplicitResultType() const { return ExplicitResultType; }
+ bool hasExplicitResultType() const {
+ return LambdaExprBits.ExplicitResultType;
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() == LambdaExprClass;
@@ -2038,15 +2037,9 @@ public:
SourceLocation getEndLoc() const LLVM_READONLY { return ClosingBrace; }
- child_range children() {
- // Includes initialization exprs plus body stmt
- return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
- }
-
- const_child_range children() const {
- return const_child_range(getStoredStmts(),
- getStoredStmts() + NumCaptures + 1);
- }
+ /// Includes the captures and the body of the lambda.
+ child_range children();
+ const_child_range children() const;
};
/// An expression "T()" which creates a value-initialized rvalue of type
@@ -2061,11 +2054,10 @@ public:
/// expression.
CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
SourceLocation RParenLoc)
- : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, false,
- false, Type->isInstantiationDependentType(),
- Type->containsUnexpandedParameterPack()),
+ : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary),
TypeInfo(TypeInfo) {
CXXScalarValueInitExprBits.RParenLoc = RParenLoc;
+ setDependence(computeDependence(this));
}
explicit CXXScalarValueInitExpr(EmptyShell Shell)
@@ -2370,15 +2362,14 @@ public:
CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm,
bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize,
FunctionDecl *OperatorDelete, Expr *Arg, SourceLocation Loc)
- : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary, false,
- Arg->isValueDependent(), Arg->isInstantiationDependent(),
- Arg->containsUnexpandedParameterPack()),
+ : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary),
OperatorDelete(OperatorDelete), Argument(Arg) {
CXXDeleteExprBits.GlobalDelete = GlobalDelete;
CXXDeleteExprBits.ArrayForm = ArrayForm;
CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten;
CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
CXXDeleteExprBits.Loc = Loc;
+ setDependence(computeDependence(this));
}
explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {}
@@ -2736,15 +2727,15 @@ public:
friend class ASTStmtReader;
ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
- TypeSourceInfo *queried, uint64_t value,
- Expr *dimension, SourceLocation rparen, QualType ty)
- : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
- false, queried->getType()->isDependentType(),
- (queried->getType()->isInstantiationDependentType() ||
- (dimension && dimension->isInstantiationDependent())),
- queried->getType()->containsUnexpandedParameterPack()),
- ATT(att), Value(value), Dimension(dimension),
- Loc(loc), RParen(rparen), QueriedType(queried) {}
+ TypeSourceInfo *queried, uint64_t value, Expr *dimension,
+ SourceLocation rparen, QualType ty)
+ : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary), ATT(att),
+ Value(value), Dimension(dimension), Loc(loc), RParen(rparen),
+ QueriedType(queried) {
+ assert(att <= ATT_Last && "invalid enum value!");
+ assert(static_cast<unsigned>(att) == ATT && "ATT overflow!");
+ setDependence(computeDependence(this));
+ }
explicit ArrayTypeTraitExpr(EmptyShell Empty)
: Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {}
@@ -2802,17 +2793,15 @@ class ExpressionTraitExpr : public Expr {
public:
friend class ASTStmtReader;
- ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et,
- Expr *queried, bool value,
- SourceLocation rparen, QualType resultType)
- : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary,
- false, // Not type-dependent
- // Value-dependent if the argument is type-dependent.
- queried->isTypeDependent(),
- queried->isInstantiationDependent(),
- queried->containsUnexpandedParameterPack()),
+ ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried,
+ bool value, SourceLocation rparen, QualType resultType)
+ : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary),
ET(et), Value(value), Loc(loc), RParen(rparen),
- QueriedExpression(queried) {}
+ QueriedExpression(queried) {
+ assert(et <= ET_Last && "invalid enum value!");
+ assert(static_cast<unsigned>(et) == ET && "ET overflow!");
+ setDependence(computeDependence(this));
+ }
explicit ExpressionTraitExpr(EmptyShell Empty)
: Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {}
@@ -3306,13 +3295,15 @@ public:
/// literal is the extent of the enclosing scope.
class ExprWithCleanups final
: public FullExpr,
- private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> {
+ private llvm::TrailingObjects<
+ ExprWithCleanups,
+ llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>> {
public:
/// The type of objects that are kept in the cleanup.
- /// It's useful to remember the set of blocks; we could also
- /// remember the set of temporaries, but there's currently
- /// no need.
- using CleanupObject = BlockDecl *;
+ /// It's useful to remember the set of blocks and block-scoped compound
+ /// literals; we could also remember the set of temporaries, but there's
+ /// currently no need.
+ using CleanupObject = llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>;
private:
friend class ASTStmtReader;
@@ -3965,13 +3956,10 @@ class CXXNoexceptExpr : public Expr {
public:
CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val,
SourceLocation Keyword, SourceLocation RParen)
- : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
- /*TypeDependent*/ false,
- /*ValueDependent*/ Val == CT_Dependent,
- Val == CT_Dependent || Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
+ : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary),
Operand(Operand), Range(Keyword, RParen) {
CXXNoexceptExprBits.Value = Val == CT_Cannot;
+ setDependence(computeDependence(this, Val));
}
CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {}
@@ -4032,12 +4020,12 @@ public:
PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
Optional<unsigned> NumExpansions)
: Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
- Pattern->getObjectKind(), /*TypeDependent=*/true,
- /*ValueDependent=*/true, /*InstantiationDependent=*/true,
- /*ContainsUnexpandedParameterPack=*/false),
+ Pattern->getObjectKind()),
EllipsisLoc(EllipsisLoc),
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0),
- Pattern(Pattern) {}
+ Pattern(Pattern) {
+ setDependence(computeDependence(this));
+ }
PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {}
@@ -4124,17 +4112,17 @@ class SizeOfPackExpr final
/// the given parameter pack.
SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
SourceLocation PackLoc, SourceLocation RParenLoc,
- Optional<unsigned> Length, ArrayRef<TemplateArgument> PartialArgs)
- : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
- /*TypeDependent=*/false, /*ValueDependent=*/!Length,
- /*InstantiationDependent=*/!Length,
- /*ContainsUnexpandedParameterPack=*/false),
+ Optional<unsigned> Length,
+ ArrayRef<TemplateArgument> PartialArgs)
+ : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary),
OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
Length(Length ? *Length : PartialArgs.size()), Pack(Pack) {
assert((!Length || PartialArgs.empty()) &&
"have partial args for non-dependent sizeof... expression");
auto *Args = getTrailingObjects<TemplateArgument>();
std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args);
+ setDependence(Length ? ExprDependence::None
+ : ExprDependence::ValueInstantiation);
}
/// Create an empty expression.
@@ -4225,12 +4213,10 @@ public:
SourceLocation Loc,
NonTypeTemplateParmDecl *Param,
Expr *Replacement)
- : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary,
- Replacement->isTypeDependent(), Replacement->isValueDependent(),
- Replacement->isInstantiationDependent(),
- Replacement->containsUnexpandedParameterPack()),
+ : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary),
Param(Param), Replacement(Replacement) {
SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
+ setDependence(computeDependence(this));
}
SourceLocation getNameLoc() const {
@@ -4544,13 +4530,12 @@ public:
CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS,
BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS,
SourceLocation RParenLoc, Optional<unsigned> NumExpansions)
- : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary,
- /*Dependent*/ true, true, true,
- /*ContainsUnexpandedParameterPack*/ false),
- LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
+ : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary), LParenLoc(LParenLoc),
+ EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
SubExprs[0] = LHS;
SubExprs[1] = RHS;
+ setDependence(computeDependence(this));
}
CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
@@ -4625,27 +4610,25 @@ public:
Expr *Ready, Expr *Suspend, Expr *Resume,
OpaqueValueExpr *OpaqueValue)
: Expr(SC, Resume->getType(), Resume->getValueKind(),
- Resume->getObjectKind(), Resume->isTypeDependent(),
- Resume->isValueDependent(), Common->isInstantiationDependent(),
- Common->containsUnexpandedParameterPack()),
+ Resume->getObjectKind()),
KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) {
SubExprs[SubExpr::Common] = Common;
SubExprs[SubExpr::Ready] = Ready;
SubExprs[SubExpr::Suspend] = Suspend;
SubExprs[SubExpr::Resume] = Resume;
+ setDependence(computeDependence(this));
}
CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty,
Expr *Common)
- : Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true,
- Common->containsUnexpandedParameterPack()),
- KeywordLoc(KeywordLoc) {
+ : Expr(SC, Ty, VK_RValue, OK_Ordinary), KeywordLoc(KeywordLoc) {
assert(Common->isTypeDependent() && Ty->isDependentType() &&
"wrong constructor for non-dependent co_await/co_yield expression");
SubExprs[SubExpr::Common] = Common;
SubExprs[SubExpr::Ready] = nullptr;
SubExprs[SubExpr::Suspend] = nullptr;
SubExprs[SubExpr::Resume] = nullptr;
+ setDependence(computeDependence(this));
}
CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
@@ -4742,10 +4725,7 @@ class DependentCoawaitExpr : public Expr {
public:
DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op,
UnresolvedLookupExpr *OpCoawait)
- : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary,
- /*TypeDependent*/ true, /*ValueDependent*/ true,
- /*InstantiationDependent*/ true,
- Op->containsUnexpandedParameterPack()),
+ : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary),
KeywordLoc(KeywordLoc) {
// NOTE: A co_await expression is dependent on the coroutines promise
// type and may be dependent even when the `Op` expression is not.
@@ -4753,6 +4733,7 @@ public:
"wrong constructor for non-dependent co_await/co_yield expression");
SubExprs[0] = Op;
SubExprs[1] = OpCoawait;
+ setDependence(computeDependence(this));
}
DependentCoawaitExpr(EmptyShell Empty)
@@ -4827,6 +4808,8 @@ public:
: ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0,
DstType),
KWLoc(KWLoc), RParenLoc(RParenLoc) {}
+ BuiltinBitCastExpr(EmptyShell Empty)
+ : ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0) {}
SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; }
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
@@ -4836,99 +4819,6 @@ public:
}
};
-/// \brief Represents the specialization of a concept - evaluates to a prvalue
-/// of type bool.
-///
-/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
-/// specialization of a concept results in a prvalue of type bool.
-class ConceptSpecializationExpr final : public Expr, public ConceptReference,
- private llvm::TrailingObjects<ConceptSpecializationExpr,
- TemplateArgument> {
- friend class ASTStmtReader;
- friend TrailingObjects;
-public:
- using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
-
-protected:
- /// \brief The number of template arguments in the tail-allocated list of
- /// converted template arguments.
- unsigned NumTemplateArgs;
-
- /// \brief Information about the satisfaction of the named concept with the
- /// given arguments. If this expression is value dependent, this is to be
- /// ignored.
- ASTConstraintSatisfaction *Satisfaction;
-
- ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc,
- DeclarationNameInfo ConceptNameInfo,
- NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs,
- const ConstraintSatisfaction *Satisfaction);
-
- ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
-
-public:
-
- static ConceptSpecializationExpr *
- Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
- NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs,
- const ConstraintSatisfaction *Satisfaction);
-
- static ConceptSpecializationExpr *
- Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
-
- ArrayRef<TemplateArgument> getTemplateArguments() const {
- return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
- NumTemplateArgs);
- }
-
- /// \brief Set new template arguments for this concept specialization.
- void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
-
- /// \brief Whether or not the concept with the given arguments was satisfied
- /// when the expression was created.
- /// The expression must not be dependent.
- bool isSatisfied() const {
- assert(!isValueDependent()
- && "isSatisfied called on a dependent ConceptSpecializationExpr");
- return Satisfaction->IsSatisfied;
- }
-
- /// \brief Get elaborated satisfaction info about the template arguments'
- /// satisfaction of the named concept.
- /// The expression must not be dependent.
- const ASTConstraintSatisfaction &getSatisfaction() const {
- assert(!isValueDependent()
- && "getSatisfaction called on dependent ConceptSpecializationExpr");
- return *Satisfaction;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ConceptSpecializationExprClass;
- }
-
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return ConceptName.getBeginLoc();
- }
-
- SourceLocation getEndLoc() const LLVM_READONLY {
- return ArgsAsWritten->RAngleLoc;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-};
-
} // namespace clang
#endif // LLVM_CLANG_AST_EXPRCXX_H
diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h
new file mode 100644
index 000000000000..2a88ed5175d2
--- /dev/null
+++ b/clang/include/clang/AST/ExprConcepts.h
@@ -0,0 +1,554 @@
+//===- ExprConcepts.h - C++2a Concepts expressions --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Defines Expressions and AST nodes for C++2a concepts.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H
+#define LLVM_CLANG_AST_EXPRCONCEPTS_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConcept.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/TrailingObjects.h"
+#include <utility>
+#include <string>
+
+namespace clang {
+class ASTStmtReader;
+class ASTStmtWriter;
+
+/// \brief Represents the specialization of a concept - evaluates to a prvalue
+/// of type bool.
+///
+/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
+/// specialization of a concept results in a prvalue of type bool.
+class ConceptSpecializationExpr final : public Expr, public ConceptReference,
+ private llvm::TrailingObjects<ConceptSpecializationExpr,
+ TemplateArgument> {
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+public:
+ using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
+
+protected:
+ /// \brief The number of template arguments in the tail-allocated list of
+ /// converted template arguments.
+ unsigned NumTemplateArgs;
+
+ /// \brief Information about the satisfaction of the named concept with the
+ /// given arguments. If this expression is value dependent, this is to be
+ /// ignored.
+ ASTConstraintSatisfaction *Satisfaction;
+
+ ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
+ SourceLocation TemplateKWLoc,
+ DeclarationNameInfo ConceptNameInfo,
+ NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
+ const ASTTemplateArgumentListInfo *ArgsAsWritten,
+ ArrayRef<TemplateArgument> ConvertedArgs,
+ const ConstraintSatisfaction *Satisfaction);
+
+ ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept,
+ ArrayRef<TemplateArgument> ConvertedArgs,
+ const ConstraintSatisfaction *Satisfaction,
+ bool Dependent,
+ bool ContainsUnexpandedParameterPack);
+
+ ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
+
+public:
+
+ static ConceptSpecializationExpr *
+ Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
+ SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
+ NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
+ const ASTTemplateArgumentListInfo *ArgsAsWritten,
+ ArrayRef<TemplateArgument> ConvertedArgs,
+ const ConstraintSatisfaction *Satisfaction);
+
+ static ConceptSpecializationExpr *
+ Create(const ASTContext &C, ConceptDecl *NamedConcept,
+ ArrayRef<TemplateArgument> ConvertedArgs,
+ const ConstraintSatisfaction *Satisfaction,
+ bool Dependent,
+ bool ContainsUnexpandedParameterPack);
+
+ static ConceptSpecializationExpr *
+ Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
+
+ ArrayRef<TemplateArgument> getTemplateArguments() const {
+ return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
+ NumTemplateArgs);
+ }
+
+ /// \brief Set new template arguments for this concept specialization.
+ void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
+
+ /// \brief Whether or not the concept with the given arguments was satisfied
+ /// when the expression was created.
+ /// The expression must not be dependent.
+ bool isSatisfied() const {
+ assert(!isValueDependent()
+ && "isSatisfied called on a dependent ConceptSpecializationExpr");
+ return Satisfaction->IsSatisfied;
+ }
+
+ /// \brief Get elaborated satisfaction info about the template arguments'
+ /// satisfaction of the named concept.
+ /// The expression must not be dependent.
+ const ASTConstraintSatisfaction &getSatisfaction() const {
+ assert(!isValueDependent()
+ && "getSatisfaction called on dependent ConceptSpecializationExpr");
+ return *Satisfaction;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ConceptSpecializationExprClass;
+ }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return ConceptName.getBeginLoc();
+ }
+
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return ArgsAsWritten->RAngleLoc;
+ }
+
+ // Iterators
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+};
+
+namespace concepts {
+
+/// \brief A static requirement that can be used in a requires-expression to
+/// check properties of types and expression.
+class Requirement {
+public:
+ // Note - simple and compound requirements are both represented by the same
+ // class (ExprRequirement).
+ enum RequirementKind { RK_Type, RK_Simple, RK_Compound, RK_Nested };
+private:
+ const RequirementKind Kind;
+ // FIXME: use RequirementDependence to model dependence?
+ bool Dependent : 1;
+ bool ContainsUnexpandedParameterPack : 1;
+ bool Satisfied : 1;
+public:
+ struct SubstitutionDiagnostic {
+ StringRef SubstitutedEntity;
+ // FIXME: Store diagnostics semantically and not as prerendered strings.
+ // Fixing this probably requires serialization of PartialDiagnostic
+ // objects.
+ SourceLocation DiagLoc;
+ StringRef DiagMessage;
+ };
+
+ Requirement(RequirementKind Kind, bool IsDependent,
+ bool ContainsUnexpandedParameterPack, bool IsSatisfied = true) :
+ Kind(Kind), Dependent(IsDependent),
+ ContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack),
+ Satisfied(IsSatisfied) {}
+
+ RequirementKind getKind() const { return Kind; }
+
+ bool isSatisfied() const {
+ assert(!Dependent &&
+ "isSatisfied can only be called on non-dependent requirements.");
+ return Satisfied;
+ }
+
+ void setSatisfied(bool IsSatisfied) {
+ assert(!Dependent &&
+ "setSatisfied can only be called on non-dependent requirements.");
+ Satisfied = IsSatisfied;
+ }
+
+ void setDependent(bool IsDependent) { Dependent = IsDependent; }
+ bool isDependent() const { return Dependent; }
+
+ void setContainsUnexpandedParameterPack(bool Contains) {
+ ContainsUnexpandedParameterPack = Contains;
+ }
+ bool containsUnexpandedParameterPack() const {
+ return ContainsUnexpandedParameterPack;
+ }
+};
+
+/// \brief A requires-expression requirement which queries the existence of a
+/// type name or type template specialization ('type' requirements).
+class TypeRequirement : public Requirement {
+public:
+ enum SatisfactionStatus {
+ SS_Dependent,
+ SS_SubstitutionFailure,
+ SS_Satisfied
+ };
+private:
+ llvm::PointerUnion<SubstitutionDiagnostic *, TypeSourceInfo *> Value;
+ SatisfactionStatus Status;
+public:
+ friend ASTStmtReader;
+ friend ASTStmtWriter;
+
+ /// \brief Construct a type requirement from a type. If the given type is not
+ /// dependent, this indicates that the type exists and the requirement will be
+ /// satisfied. Otherwise, the SubstitutionDiagnostic constructor is to be
+ /// used.
+ TypeRequirement(TypeSourceInfo *T);
+
+ /// \brief Construct a type requirement when the nested name specifier is
+ /// invalid due to a bad substitution. The requirement is unsatisfied.
+ TypeRequirement(SubstitutionDiagnostic *Diagnostic) :
+ Requirement(RK_Type, false, false, false), Value(Diagnostic),
+ Status(SS_SubstitutionFailure) {}
+
+ SatisfactionStatus getSatisfactionStatus() const { return Status; }
+ void setSatisfactionStatus(SatisfactionStatus Status) {
+ this->Status = Status;
+ }
+
+ bool isSubstitutionFailure() const {
+ return Status == SS_SubstitutionFailure;
+ }
+
+ SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
+ assert(Status == SS_SubstitutionFailure &&
+ "Attempted to get substitution diagnostic when there has been no "
+ "substitution failure.");
+ return Value.get<SubstitutionDiagnostic *>();
+ }
+
+ TypeSourceInfo *getType() const {
+ assert(!isSubstitutionFailure() &&
+ "Attempted to get type when there has been a substitution failure.");
+ return Value.get<TypeSourceInfo *>();
+ }
+
+ static bool classof(const Requirement *R) {
+ return R->getKind() == RK_Type;
+ }
+};
+
+/// \brief A requires-expression requirement which queries the validity and
+/// properties of an expression ('simple' and 'compound' requirements).
+class ExprRequirement : public Requirement {
+public:
+ enum SatisfactionStatus {
+ SS_Dependent,
+ SS_ExprSubstitutionFailure,
+ SS_NoexceptNotMet,
+ SS_TypeRequirementSubstitutionFailure,
+ SS_ConstraintsNotSatisfied,
+ SS_Satisfied
+ };
+ class ReturnTypeRequirement {
+ llvm::PointerIntPair<
+ llvm::PointerUnion<TemplateParameterList *, SubstitutionDiagnostic *>,
+ 1, bool>
+ TypeConstraintInfo;
+ public:
+ friend ASTStmtReader;
+ friend ASTStmtWriter;
+
+ /// \brief No return type requirement was specified.
+ ReturnTypeRequirement() : TypeConstraintInfo(nullptr, 0) {}
+
+ /// \brief A return type requirement was specified but it was a
+ /// substitution failure.
+ ReturnTypeRequirement(SubstitutionDiagnostic *SubstDiag) :
+ TypeConstraintInfo(SubstDiag, 0) {}
+
+ /// \brief A 'type constraint' style return type requirement.
+ /// \param TPL an invented template parameter list containing a single
+ /// type parameter with a type-constraint.
+ // TODO: Can we maybe not save the whole template parameter list and just
+ // the type constraint? Saving the whole TPL makes it easier to handle in
+ // serialization but is less elegant.
+ ReturnTypeRequirement(TemplateParameterList *TPL);
+
+ bool isDependent() const {
+ return TypeConstraintInfo.getInt();
+ }
+
+ bool containsUnexpandedParameterPack() const {
+ if (!isTypeConstraint())
+ return false;
+ return getTypeConstraintTemplateParameterList()
+ ->containsUnexpandedParameterPack();
+ }
+
+ bool isEmpty() const {
+ return TypeConstraintInfo.getPointer().isNull();
+ }
+
+ bool isSubstitutionFailure() const {
+ return !isEmpty() &&
+ TypeConstraintInfo.getPointer().is<SubstitutionDiagnostic *>();
+ }
+
+ bool isTypeConstraint() const {
+ return !isEmpty() &&
+ TypeConstraintInfo.getPointer().is<TemplateParameterList *>();
+ }
+
+ SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
+ assert(isSubstitutionFailure());
+ return TypeConstraintInfo.getPointer().get<SubstitutionDiagnostic *>();
+ }
+
+ const TypeConstraint *getTypeConstraint() const;
+
+ TemplateParameterList *getTypeConstraintTemplateParameterList() const {
+ assert(isTypeConstraint());
+ return TypeConstraintInfo.getPointer().get<TemplateParameterList *>();
+ }
+ };
+private:
+ llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value;
+ SourceLocation NoexceptLoc; // May be empty if noexcept wasn't specified.
+ ReturnTypeRequirement TypeReq;
+ ConceptSpecializationExpr *SubstitutedConstraintExpr;
+ SatisfactionStatus Status;
+public:
+ friend ASTStmtReader;
+ friend ASTStmtWriter;
+
+ /// \brief Construct a compound requirement.
+ /// \param E the expression which is checked by this requirement.
+ /// \param IsSimple whether this was a simple requirement in source.
+ /// \param NoexceptLoc the location of the noexcept keyword, if it was
+ /// specified, otherwise an empty location.
+ /// \param Req the requirement for the type of the checked expression.
+ /// \param Status the satisfaction status of this requirement.
+ ExprRequirement(
+ Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
+ ReturnTypeRequirement Req, SatisfactionStatus Status,
+ ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr);
+
+ /// \brief Construct a compound requirement whose expression was a
+ /// substitution failure. The requirement is not satisfied.
+ /// \param E the diagnostic emitted while instantiating the original
+ /// expression.
+ /// \param IsSimple whether this was a simple requirement in source.
+ /// \param NoexceptLoc the location of the noexcept keyword, if it was
+ /// specified, otherwise an empty location.
+ /// \param Req the requirement for the type of the checked expression (omit
+ /// if no requirement was specified).
+ ExprRequirement(SubstitutionDiagnostic *E, bool IsSimple,
+ SourceLocation NoexceptLoc, ReturnTypeRequirement Req = {});
+
+ bool isSimple() const { return getKind() == RK_Simple; }
+ bool isCompound() const { return getKind() == RK_Compound; }
+
+ bool hasNoexceptRequirement() const { return NoexceptLoc.isValid(); }
+ SourceLocation getNoexceptLoc() const { return NoexceptLoc; }
+
+ SatisfactionStatus getSatisfactionStatus() const { return Status; }
+
+ bool isExprSubstitutionFailure() const {
+ return Status == SS_ExprSubstitutionFailure;
+ }
+
+ const ReturnTypeRequirement &getReturnTypeRequirement() const {
+ return TypeReq;
+ }
+
+ ConceptSpecializationExpr *
+ getReturnTypeRequirementSubstitutedConstraintExpr() const {
+ assert(Status >= SS_TypeRequirementSubstitutionFailure);
+ return SubstitutedConstraintExpr;
+ }
+
+ SubstitutionDiagnostic *getExprSubstitutionDiagnostic() const {
+ assert(isExprSubstitutionFailure() &&
+ "Attempted to get expression substitution diagnostic when there has "
+ "been no expression substitution failure");
+ return Value.get<SubstitutionDiagnostic *>();
+ }
+
+ Expr *getExpr() const {
+ assert(!isExprSubstitutionFailure() &&
+ "ExprRequirement has no expression because there has been a "
+ "substitution failure.");
+ return Value.get<Expr *>();
+ }
+
+ static bool classof(const Requirement *R) {
+ return R->getKind() == RK_Compound || R->getKind() == RK_Simple;
+ }
+};
+
+/// \brief A requires-expression requirement which is satisfied when a general
+/// constraint expression is satisfied ('nested' requirements).
+class NestedRequirement : public Requirement {
+ llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value;
+ const ASTConstraintSatisfaction *Satisfaction = nullptr;
+
+public:
+ friend ASTStmtReader;
+ friend ASTStmtWriter;
+
+ NestedRequirement(SubstitutionDiagnostic *SubstDiag) :
+ Requirement(RK_Nested, /*Dependent=*/false,
+ /*ContainsUnexpandedParameterPack*/false,
+ /*Satisfied=*/false), Value(SubstDiag) {}
+
+ NestedRequirement(Expr *Constraint) :
+ Requirement(RK_Nested, /*Dependent=*/true,
+ Constraint->containsUnexpandedParameterPack()),
+ Value(Constraint) {
+ assert(Constraint->isInstantiationDependent() &&
+ "Nested requirement with non-dependent constraint must be "
+ "constructed with a ConstraintSatisfaction object");
+ }
+
+ NestedRequirement(ASTContext &C, Expr *Constraint,
+ const ConstraintSatisfaction &Satisfaction) :
+ Requirement(RK_Nested, Constraint->isInstantiationDependent(),
+ Constraint->containsUnexpandedParameterPack(),
+ Satisfaction.IsSatisfied),
+ Value(Constraint),
+ Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
+
+ bool isSubstitutionFailure() const {
+ return Value.is<SubstitutionDiagnostic *>();
+ }
+
+ SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
+ assert(isSubstitutionFailure() &&
+ "getSubstitutionDiagnostic() may not be called when there was no "
+ "substitution failure.");
+ return Value.get<SubstitutionDiagnostic *>();
+ }
+
+ Expr *getConstraintExpr() const {
+ assert(!isSubstitutionFailure() && "getConstraintExpr() may not be called "
+ "on nested requirements with "
+ "substitution failures.");
+ return Value.get<Expr *>();
+ }
+
+ const ASTConstraintSatisfaction &getConstraintSatisfaction() const {
+ assert(!isSubstitutionFailure() && "getConstraintSatisfaction() may not be "
+ "called on nested requirements with "
+ "substitution failures.");
+ return *Satisfaction;
+ }
+
+ static bool classof(const Requirement *R) {
+ return R->getKind() == RK_Nested;
+ }
+};
+
+} // namespace concepts
+
+/// C++2a [expr.prim.req]:
+/// A requires-expression provides a concise way to express requirements on
+/// template arguments. A requirement is one that can be checked by name
+/// lookup (6.4) or by checking properties of types and expressions.
+/// [...]
+/// A requires-expression is a prvalue of type bool [...]
+class RequiresExpr final : public Expr,
+ llvm::TrailingObjects<RequiresExpr, ParmVarDecl *,
+ concepts::Requirement *> {
+ friend TrailingObjects;
+ friend class ASTStmtReader;
+
+ unsigned NumLocalParameters;
+ unsigned NumRequirements;
+ RequiresExprBodyDecl *Body;
+ SourceLocation RBraceLoc;
+
+ unsigned numTrailingObjects(OverloadToken<ParmVarDecl *>) const {
+ return NumLocalParameters;
+ }
+
+ unsigned numTrailingObjects(OverloadToken<concepts::Requirement *>) const {
+ return NumRequirements;
+ }
+
+ RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
+ RequiresExprBodyDecl *Body,
+ ArrayRef<ParmVarDecl *> LocalParameters,
+ ArrayRef<concepts::Requirement *> Requirements,
+ SourceLocation RBraceLoc);
+ RequiresExpr(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
+ unsigned NumRequirements);
+
+public:
+ static RequiresExpr *
+ Create(ASTContext &C, SourceLocation RequiresKWLoc,
+ RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> LocalParameters,
+ ArrayRef<concepts::Requirement *> Requirements,
+ SourceLocation RBraceLoc);
+ static RequiresExpr *
+ Create(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
+ unsigned NumRequirements);
+
+ ArrayRef<ParmVarDecl *> getLocalParameters() const {
+ return {getTrailingObjects<ParmVarDecl *>(), NumLocalParameters};
+ }
+
+ RequiresExprBodyDecl *getBody() const { return Body; }
+
+ ArrayRef<concepts::Requirement *> getRequirements() const {
+ return {getTrailingObjects<concepts::Requirement *>(), NumRequirements};
+ }
+
+ /// \brief Whether or not the requires clause is satisfied.
+ /// The expression must not be dependent.
+ bool isSatisfied() const {
+ assert(!isValueDependent()
+ && "isSatisfied called on a dependent RequiresExpr");
+ return RequiresExprBits.IsSatisfied;
+ }
+
+ SourceLocation getRequiresKWLoc() const {
+ return RequiresExprBits.RequiresKWLoc;
+ }
+
+ SourceLocation getRBraceLoc() const { return RBraceLoc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == RequiresExprClass;
+ }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return RequiresExprBits.RequiresKWLoc;
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return RBraceLoc;
+ }
+
+ // Iterators
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_EXPRCONCEPTS_H
diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h
index d76b3a26b1f9..4b39d9ab96a6 100644
--- a/clang/include/clang/AST/ExprObjC.h
+++ b/clang/include/clang/AST/ExprObjC.h
@@ -13,8 +13,10 @@
#ifndef LLVM_CLANG_AST_EXPROBJC_H
#define LLVM_CLANG_AST_EXPROBJC_H
+#include "clang/AST/ComputeDependence.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DependenceFlags.h"
#include "clang/AST/Expr.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/SelectorLocationsKind.h"
@@ -53,9 +55,10 @@ class ObjCStringLiteral : public Expr {
public:
ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
- : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- String(SL), AtLoc(L) {}
+ : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary), String(SL),
+ AtLoc(L) {
+ setDependence(ExprDependence::None);
+ }
explicit ObjCStringLiteral(EmptyShell Empty)
: Expr(ObjCStringLiteralClass, Empty) {}
@@ -88,9 +91,10 @@ class ObjCBoolLiteralExpr : public Expr {
public:
ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l)
- : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Value(val), Loc(l) {}
+ : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary), Value(val),
+ Loc(l) {
+ setDependence(ExprDependence::None);
+ }
explicit ObjCBoolLiteralExpr(EmptyShell Empty)
: Expr(ObjCBoolLiteralExprClass, Empty) {}
@@ -129,13 +133,11 @@ class ObjCBoxedExpr : public Expr {
public:
friend class ASTStmtReader;
- ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
- SourceRange R)
- : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
- E->isTypeDependent(), E->isValueDependent(),
- E->isInstantiationDependent(),
- E->containsUnexpandedParameterPack()),
- SubExpr(E), BoxingMethod(method), Range(R) {}
+ ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, SourceRange R)
+ : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary), SubExpr(E),
+ BoxingMethod(method), Range(R) {
+ setDependence(computeDependence(this));
+ }
explicit ObjCBoxedExpr(EmptyShell Empty)
: Expr(ObjCBoxedExprClass, Empty) {}
@@ -409,14 +411,12 @@ class ObjCEncodeExpr : public Expr {
SourceLocation AtLoc, RParenLoc;
public:
- ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
- SourceLocation at, SourceLocation rp)
- : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
- EncodedType->getType()->isDependentType(),
- EncodedType->getType()->isDependentType(),
- EncodedType->getType()->isInstantiationDependentType(),
- EncodedType->getType()->containsUnexpandedParameterPack()),
- EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
+ ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, SourceLocation at,
+ SourceLocation rp)
+ : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary),
+ EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {
+ setDependence(computeDependence(this));
+ }
explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
@@ -456,11 +456,12 @@ class ObjCSelectorExpr : public Expr {
SourceLocation AtLoc, RParenLoc;
public:
- ObjCSelectorExpr(QualType T, Selector selInfo,
- SourceLocation at, SourceLocation rp)
- : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- SelName(selInfo), AtLoc(at), RParenLoc(rp) {}
+ ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at,
+ SourceLocation rp)
+ : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary),
+ SelName(selInfo), AtLoc(at), RParenLoc(rp) {
+ setDependence(ExprDependence::None);
+ }
explicit ObjCSelectorExpr(EmptyShell Empty)
: Expr(ObjCSelectorExprClass, Empty) {}
@@ -508,11 +509,12 @@ public:
friend class ASTStmtReader;
friend class ASTStmtWriter;
- ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
- SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
- : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
+ ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at,
+ SourceLocation protoLoc, SourceLocation rp)
+ : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary),
+ TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {
+ setDependence(ExprDependence::None);
+ }
explicit ObjCProtocolExpr(EmptyShell Empty)
: Expr(ObjCProtocolExprClass, Empty) {}
@@ -558,17 +560,15 @@ class ObjCIvarRefExpr : public Expr {
bool IsFreeIvar : 1;
public:
- ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
- SourceLocation l, SourceLocation oploc,
- Expr *base,
- bool arrow = false, bool freeIvar = false)
+ ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, SourceLocation l,
+ SourceLocation oploc, Expr *base, bool arrow = false,
+ bool freeIvar = false)
: Expr(ObjCIvarRefExprClass, t, VK_LValue,
- d->isBitField() ? OK_BitField : OK_Ordinary,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
+ d->isBitField() ? OK_BitField : OK_Ordinary),
D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow),
- IsFreeIvar(freeIvar) {}
+ IsFreeIvar(freeIvar) {
+ setDependence(computeDependence(this));
+ }
explicit ObjCIvarRefExpr(EmptyShell Empty)
: Expr(ObjCIvarRefExprClass, Empty) {}
@@ -645,57 +645,53 @@ private:
llvm::PointerUnion<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver;
public:
- ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation l, Expr *base)
- : Expr(ObjCPropertyRefExprClass, t, VK, OK,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- PropertyOrGetter(PD, false), IdLoc(l), Receiver(base) {
+ ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation l, Expr *base)
+ : Expr(ObjCPropertyRefExprClass, t, VK, OK), PropertyOrGetter(PD, false),
+ IdLoc(l), Receiver(base) {
assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+ setDependence(computeDependence(this));
}
- ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation l, SourceLocation sl, QualType st)
- : Expr(ObjCPropertyRefExprClass, t, VK, OK,
- /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
- st->containsUnexpandedParameterPack()),
- PropertyOrGetter(PD, false), IdLoc(l), ReceiverLoc(sl),
- Receiver(st.getTypePtr()) {
+ ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation l, SourceLocation sl,
+ QualType st)
+ : Expr(ObjCPropertyRefExprClass, t, VK, OK), PropertyOrGetter(PD, false),
+ IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+ setDependence(computeDependence(this));
}
ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
QualType T, ExprValueKind VK, ExprObjectKind OK,
SourceLocation IdLoc, Expr *Base)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
- Base->isValueDependent(), Base->isInstantiationDependent(),
- Base->containsUnexpandedParameterPack()),
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK),
PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
IdLoc(IdLoc), Receiver(Base) {
assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+ setDependence(computeDependence(this));
}
ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
QualType T, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation IdLoc,
- SourceLocation SuperLoc, QualType SuperTy)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
+ SourceLocation IdLoc, SourceLocation SuperLoc,
+ QualType SuperTy)
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK),
PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+ setDependence(computeDependence(this));
}
ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
QualType T, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation IdLoc,
- SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
+ SourceLocation IdLoc, SourceLocation ReceiverLoc,
+ ObjCInterfaceDecl *Receiver)
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK),
PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+ setDependence(computeDependence(this));
}
explicit ObjCPropertyRefExpr(EmptyShell Empty)
@@ -859,20 +855,14 @@ class ObjCSubscriptRefExpr : public Expr {
ObjCMethodDecl *SetAtIndexMethodDecl;
public:
- ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
- ExprValueKind VK, ExprObjectKind OK,
- ObjCMethodDecl *getMethod,
+ ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, ExprValueKind VK,
+ ExprObjectKind OK, ObjCMethodDecl *getMethod,
ObjCMethodDecl *setMethod, SourceLocation RB)
- : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
- base->isTypeDependent() || key->isTypeDependent(),
- base->isValueDependent() || key->isValueDependent(),
- (base->isInstantiationDependent() ||
- key->isInstantiationDependent()),
- (base->containsUnexpandedParameterPack() ||
- key->containsUnexpandedParameterPack())),
- RBracket(RB), GetAtIndexMethodDecl(getMethod),
- SetAtIndexMethodDecl(setMethod) {
- SubExprs[BASE] = base; SubExprs[KEY] = key;
+ : Expr(ObjCSubscriptRefExprClass, T, VK, OK), RBracket(RB),
+ GetAtIndexMethodDecl(getMethod), SetAtIndexMethodDecl(setMethod) {
+ SubExprs[BASE] = base;
+ SubExprs[KEY] = key;
+ setDependence(computeDependence(this));
}
explicit ObjCSubscriptRefExpr(EmptyShell Empty)
@@ -1505,11 +1495,10 @@ class ObjCIsaExpr : public Expr {
public:
ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
QualType ty)
- : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- /*ContainsUnexpandedParameterPack=*/false),
- Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
+ : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary), Base(base),
+ IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {
+ setDependence(computeDependence(this));
+ }
/// Build an empty expression.
explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {}
@@ -1591,12 +1580,10 @@ class ObjCIndirectCopyRestoreExpr : public Expr {
public:
ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
- : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
- operand->isTypeDependent(), operand->isValueDependent(),
- operand->isInstantiationDependent(),
- operand->containsUnexpandedParameterPack()),
+ : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary),
Operand(operand) {
setShouldCopy(shouldCopy);
+ setDependence(computeDependence(this));
}
Expr *getSubExpr() { return cast<Expr>(Operand); }
@@ -1705,9 +1692,10 @@ class ObjCAvailabilityCheckExpr : public Expr {
public:
ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
SourceLocation RParen, QualType Ty)
- : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false,
- false, false, false),
- VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {}
+ : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary),
+ VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {
+ setDependence(ExprDependence::None);
+ }
explicit ObjCAvailabilityCheckExpr(EmptyShell Shell)
: Expr(ObjCAvailabilityCheckExprClass, Shell) {}
diff --git a/clang/include/clang/AST/ExprOpenMP.h b/clang/include/clang/AST/ExprOpenMP.h
index 5607d2d1dc58..be5dda992334 100644
--- a/clang/include/clang/AST/ExprOpenMP.h
+++ b/clang/include/clang/AST/ExprOpenMP.h
@@ -13,62 +13,66 @@
#ifndef LLVM_CLANG_AST_EXPROPENMP_H
#define LLVM_CLANG_AST_EXPROPENMP_H
+#include "clang/AST/ComputeDependence.h"
#include "clang/AST/Expr.h"
namespace clang {
-/// OpenMP 4.0 [2.4, Array Sections].
+/// OpenMP 5.0 [2.1.5, Array Sections].
/// To specify an array section in an OpenMP construct, array subscript
/// expressions are extended with the following syntax:
/// \code
+/// [ lower-bound : length : stride ]
+/// [ lower-bound : length : ]
/// [ lower-bound : length ]
+/// [ lower-bound : : stride ]
+/// [ lower-bound : : ]
/// [ lower-bound : ]
+/// [ : length : stride ]
+/// [ : length : ]
/// [ : length ]
+/// [ : : stride ]
+/// [ : : ]
/// [ : ]
/// \endcode
/// The array section must be a subset of the original array.
/// Array sections are allowed on multidimensional arrays. Base language array
/// subscript expressions can be used to specify length-one dimensions of
/// multidimensional array sections.
-/// The lower-bound and length are integral type expressions. When evaluated
+/// Each of the lower-bound, length, and stride expressions if specified must be
+/// an integral type expressions of the base language. When evaluated
/// they represent a set of integer values as follows:
/// \code
-/// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length -
-/// 1 }
+/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... ,
+/// lower-bound + ((length - 1) * stride) }
/// \endcode
/// The lower-bound and length must evaluate to non-negative integers.
+/// The stride must evaluate to a positive integer.
/// When the size of the array dimension is not known, the length must be
/// specified explicitly.
-/// When the length is absent, it defaults to the size of the array dimension
-/// minus the lower-bound.
-/// When the lower-bound is absent it defaults to 0.
+/// When the stride is absent it defaults to 1.
+/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉,
+/// where size is the size of the array dimension. When the lower-bound is
+/// absent it defaults to 0.
class OMPArraySectionExpr : public Expr {
- enum { BASE, LOWER_BOUND, LENGTH, END_EXPR };
+ enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR };
Stmt *SubExprs[END_EXPR];
- SourceLocation ColonLoc;
+ SourceLocation ColonLocFirst;
+ SourceLocation ColonLocSecond;
SourceLocation RBracketLoc;
public:
- OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation ColonLoc, SourceLocation RBracketLoc)
- : Expr(
- OMPArraySectionExprClass, Type, VK, OK,
- Base->isTypeDependent() ||
- (LowerBound && LowerBound->isTypeDependent()) ||
- (Length && Length->isTypeDependent()),
- Base->isValueDependent() ||
- (LowerBound && LowerBound->isValueDependent()) ||
- (Length && Length->isValueDependent()),
- Base->isInstantiationDependent() ||
- (LowerBound && LowerBound->isInstantiationDependent()) ||
- (Length && Length->isInstantiationDependent()),
- Base->containsUnexpandedParameterPack() ||
- (LowerBound && LowerBound->containsUnexpandedParameterPack()) ||
- (Length && Length->containsUnexpandedParameterPack())),
- ColonLoc(ColonLoc), RBracketLoc(RBracketLoc) {
+ OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride,
+ QualType Type, ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation ColonLocFirst,
+ SourceLocation ColonLocSecond, SourceLocation RBracketLoc)
+ : Expr(OMPArraySectionExprClass, Type, VK, OK),
+ ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond),
+ RBracketLoc(RBracketLoc) {
SubExprs[BASE] = Base;
SubExprs[LOWER_BOUND] = LowerBound;
SubExprs[LENGTH] = Length;
+ SubExprs[STRIDE] = Stride;
+ setDependence(computeDependence(this));
}
/// Create an empty array section expression.
@@ -100,13 +104,22 @@ public:
/// Set length of the array section.
void setLength(Expr *E) { SubExprs[LENGTH] = E; }
+ /// Get stride of array section.
+ Expr *getStride() { return cast_or_null<Expr>(SubExprs[STRIDE]); }
+ const Expr *getStride() const { return cast_or_null<Expr>(SubExprs[STRIDE]); }
+ /// Set length of the array section.
+ void setStride(Expr *E) { SubExprs[STRIDE] = E; }
+
SourceLocation getBeginLoc() const LLVM_READONLY {
return getBase()->getBeginLoc();
}
SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
+ SourceLocation getColonLocFirst() const { return ColonLocFirst; }
+ void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; }
+
+ SourceLocation getColonLocSecond() const { return ColonLocSecond; }
+ void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; }
SourceLocation getRBracketLoc() const { return RBracketLoc; }
void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
@@ -127,6 +140,286 @@ public:
return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
}
};
+
+/// An explicit cast in C or a C-style cast in C++, which uses the syntax
+/// ([s1][s2]...[sn])expr. For example: @c ([3][3])f.
+class OMPArrayShapingExpr final
+ : public Expr,
+ private llvm::TrailingObjects<OMPArrayShapingExpr, Expr *, SourceRange> {
+ friend TrailingObjects;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ /// Base node.
+ SourceLocation LPLoc; /// The location of the left paren
+ SourceLocation RPLoc; /// The location of the right paren
+ unsigned NumDims = 0; /// Number of dimensions in the shaping expression.
+
+ /// Construct full expression.
+ OMPArrayShapingExpr(QualType ExprTy, Expr *Op, SourceLocation L,
+ SourceLocation R, ArrayRef<Expr *> Dims);
+
+ /// Construct an empty expression.
+ explicit OMPArrayShapingExpr(EmptyShell Shell, unsigned NumDims)
+ : Expr(OMPArrayShapingExprClass, Shell), NumDims(NumDims) {}
+
+ /// Sets the dimensions for the array shaping.
+ void setDimensions(ArrayRef<Expr *> Dims);
+
+ /// Sets the base expression for array shaping operation.
+ void setBase(Expr *Op) { getTrailingObjects<Expr *>()[NumDims] = Op; }
+
+ /// Sets source ranges for the brackets in the array shaping operation.
+ void setBracketsRanges(ArrayRef<SourceRange> BR);
+
+ unsigned numTrailingObjects(OverloadToken<Expr *>) const {
+ // Add an extra one for the base expression.
+ return NumDims + 1;
+ }
+
+ unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
+ return NumDims;
+ }
+
+public:
+ static OMPArrayShapingExpr *Create(const ASTContext &Context, QualType T,
+ Expr *Op, SourceLocation L,
+ SourceLocation R, ArrayRef<Expr *> Dims,
+ ArrayRef<SourceRange> BracketRanges);
+
+ static OMPArrayShapingExpr *CreateEmpty(const ASTContext &Context,
+ unsigned NumDims);
+
+ SourceLocation getLParenLoc() const { return LPLoc; }
+ void setLParenLoc(SourceLocation L) { LPLoc = L; }
+
+ SourceLocation getRParenLoc() const { return RPLoc; }
+ void setRParenLoc(SourceLocation L) { RPLoc = L; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getBase()->getEndLoc();
+ }
+
+ /// Fetches the dimensions for array shaping expression.
+ ArrayRef<Expr *> getDimensions() const {
+ return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumDims);
+ }
+
+ /// Fetches source ranges for the brackets os the array shaping expression.
+ ArrayRef<SourceRange> getBracketsRanges() const {
+ return llvm::makeArrayRef(getTrailingObjects<SourceRange>(), NumDims);
+ }
+
+ /// Fetches base expression of array shaping expression.
+ Expr *getBase() { return getTrailingObjects<Expr *>()[NumDims]; }
+ const Expr *getBase() const { return getTrailingObjects<Expr *>()[NumDims]; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPArrayShapingExprClass;
+ }
+
+ // Iterators
+ child_range children() {
+ Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
+ return child_range(Begin, Begin + NumDims + 1);
+ }
+ const_child_range children() const {
+ Stmt *const *Begin =
+ reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
+ return const_child_range(Begin, Begin + NumDims + 1);
+ }
+};
+
+/// Helper expressions and declaration for OMPIteratorExpr class for each
+/// iteration space.
+struct OMPIteratorHelperData {
+ /// Internal normalized counter.
+ VarDecl *CounterVD = nullptr;
+ /// Normalized upper bound. Normalized loop iterates from 0 to Upper with
+ /// step 1.
+ Expr *Upper = nullptr;
+ /// Update expression for the originally specified iteration variable,
+ /// calculated as VD = Begin + CounterVD * Step;
+ Expr *Update = nullptr;
+ /// Updater for the internal counter: ++CounterVD;
+ Expr *CounterUpdate = nullptr;
+};
+
+/// OpenMP 5.0 [2.1.6 Iterators]
+/// Iterators are identifiers that expand to multiple values in the clause on
+/// which they appear.
+/// The syntax of the iterator modifier is as follows:
+/// \code
+/// iterator(iterators-definition)
+/// \endcode
+/// where iterators-definition is one of the following:
+/// \code
+/// iterator-specifier [, iterators-definition ]
+/// \endcode
+/// where iterator-specifier is one of the following:
+/// \code
+/// [ iterator-type ] identifier = range-specification
+/// \endcode
+/// where identifier is a base language identifier.
+/// iterator-type is a type name.
+/// range-specification is of the form begin:end[:step], where begin and end are
+/// expressions for which their types can be converted to iterator-type and step
+/// is an integral expression.
+/// In an iterator-specifier, if the iterator-type is not specified then the
+/// type of that iterator is of int type.
+/// The iterator-type must be an integral or pointer type.
+/// The iterator-type must not be const qualified.
+class OMPIteratorExpr final
+ : public Expr,
+ private llvm::TrailingObjects<OMPIteratorExpr, Decl *, Expr *,
+ SourceLocation, OMPIteratorHelperData> {
+public:
+ /// Iterator range representation begin:end[:step].
+ struct IteratorRange {
+ Expr *Begin = nullptr;
+ Expr *End = nullptr;
+ Expr *Step = nullptr;
+ };
+ /// Iterator definition representation.
+ struct IteratorDefinition {
+ Decl *IteratorDecl = nullptr;
+ IteratorRange Range;
+ SourceLocation AssignmentLoc;
+ SourceLocation ColonLoc, SecondColonLoc;
+ };
+
+private:
+ friend TrailingObjects;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
+ /// Offset in the list of expressions for subelements of the ranges.
+ enum class RangeExprOffset {
+ Begin = 0,
+ End = 1,
+ Step = 2,
+ Total = 3,
+ };
+ /// Offset in the list of locations for subelements of colon symbols
+ /// locations.
+ enum class RangeLocOffset {
+ AssignLoc = 0,
+ FirstColonLoc = 1,
+ SecondColonLoc = 2,
+ Total = 3,
+ };
+ /// Location of 'iterator' keyword.
+ SourceLocation IteratorKwLoc;
+ /// Location of '('.
+ SourceLocation LPLoc;
+ /// Location of ')'.
+ SourceLocation RPLoc;
+ /// Number of iterator definitions.
+ unsigned NumIterators = 0;
+
+ OMPIteratorExpr(QualType ExprTy, SourceLocation IteratorKwLoc,
+ SourceLocation L, SourceLocation R,
+ ArrayRef<IteratorDefinition> Data,
+ ArrayRef<OMPIteratorHelperData> Helpers);
+
+ /// Construct an empty expression.
+ explicit OMPIteratorExpr(EmptyShell Shell, unsigned NumIterators)
+ : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {}
+
+ /// Sets basic declaration for the specified iterator definition.
+ void setIteratorDeclaration(unsigned I, Decl *D);
+
+ /// Sets the location of the assignment symbol for the specified iterator
+ /// definition.
+ void setAssignmentLoc(unsigned I, SourceLocation Loc);
+
+ /// Sets begin, end and optional step expressions for specified iterator
+ /// definition.
+ void setIteratorRange(unsigned I, Expr *Begin, SourceLocation ColonLoc,
+ Expr *End, SourceLocation SecondColonLoc, Expr *Step);
+
+ /// Sets helpers for the specified iteration space.
+ void setHelper(unsigned I, const OMPIteratorHelperData &D);
+
+ unsigned numTrailingObjects(OverloadToken<Decl *>) const {
+ return NumIterators;
+ }
+
+ unsigned numTrailingObjects(OverloadToken<Expr *>) const {
+ return NumIterators * static_cast<int>(RangeExprOffset::Total);
+ }
+
+ unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
+ return NumIterators * static_cast<int>(RangeLocOffset::Total);
+ }
+
+public:
+ static OMPIteratorExpr *Create(const ASTContext &Context, QualType T,
+ SourceLocation IteratorKwLoc, SourceLocation L,
+ SourceLocation R,
+ ArrayRef<IteratorDefinition> Data,
+ ArrayRef<OMPIteratorHelperData> Helpers);
+
+ static OMPIteratorExpr *CreateEmpty(const ASTContext &Context,
+ unsigned NumIterators);
+
+ SourceLocation getLParenLoc() const { return LPLoc; }
+ void setLParenLoc(SourceLocation L) { LPLoc = L; }
+
+ SourceLocation getRParenLoc() const { return RPLoc; }
+ void setRParenLoc(SourceLocation L) { RPLoc = L; }
+
+ SourceLocation getIteratorKwLoc() const { return IteratorKwLoc; }
+ void setIteratorKwLoc(SourceLocation L) { IteratorKwLoc = L; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return IteratorKwLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RPLoc; }
+
+ /// Gets the iterator declaration for the given iterator.
+ Decl *getIteratorDecl(unsigned I);
+ const Decl *getIteratorDecl(unsigned I) const {
+ return const_cast<OMPIteratorExpr *>(this)->getIteratorDecl(I);
+ }
+
+ /// Gets the iterator range for the given iterator.
+ IteratorRange getIteratorRange(unsigned I);
+ const IteratorRange getIteratorRange(unsigned I) const {
+ return const_cast<OMPIteratorExpr *>(this)->getIteratorRange(I);
+ }
+
+ /// Gets the location of '=' for the given iterator definition.
+ SourceLocation getAssignLoc(unsigned I) const;
+ /// Gets the location of the first ':' in the range for the given iterator
+ /// definition.
+ SourceLocation getColonLoc(unsigned I) const;
+ /// Gets the location of the second ':' (if any) in the range for the given
+ /// iteratori definition.
+ SourceLocation getSecondColonLoc(unsigned I) const;
+
+ /// Returns number of iterator definitions.
+ unsigned numOfIterators() const { return NumIterators; }
+
+ /// Fetches helper data for the specified iteration space.
+ OMPIteratorHelperData &getHelper(unsigned I);
+ const OMPIteratorHelperData &getHelper(unsigned I) const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPIteratorExprClass;
+ }
+
+ // Iterators
+ child_range children() {
+ Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
+ return child_range(
+ Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total));
+ }
+ const_child_range children() const {
+ Stmt *const *Begin =
+ reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
+ return const_child_range(
+ Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total));
+ }
+};
+
} // end namespace clang
#endif
diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h
index 899ac3f66937..def877b91816 100644
--- a/clang/include/clang/AST/ExternalASTSource.h
+++ b/clang/include/clang/AST/ExternalASTSource.h
@@ -17,7 +17,6 @@
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclBase.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Module.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -39,6 +38,7 @@ namespace clang {
class ASTConsumer;
class ASTContext;
+class ASTSourceDescriptor;
class CXXBaseSpecifier;
class CXXCtorInitializer;
class CXXRecordDecl;
@@ -165,31 +165,6 @@ public:
/// object file.
virtual bool DeclIsFromPCHWithObjectFile(const Decl *D) { return false; }
- /// Abstracts clang modules and precompiled header files and holds
- /// everything needed to generate debug info for an imported module
- /// or PCH.
- class ASTSourceDescriptor {
- StringRef PCHModuleName;
- StringRef Path;
- StringRef ASTFile;
- ASTFileSignature Signature;
- const Module *ClangModule = nullptr;
-
- public:
- ASTSourceDescriptor() = default;
- ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
- ASTFileSignature Signature)
- : PCHModuleName(std::move(Name)), Path(std::move(Path)),
- ASTFile(std::move(ASTFile)), Signature(Signature) {}
- ASTSourceDescriptor(const Module &M);
-
- std::string getModuleName() const;
- StringRef getPath() const { return Path; }
- StringRef getASTFile() const { return ASTFile; }
- ASTFileSignature getSignature() const { return Signature; }
- const Module *getModuleOrNull() const { return ClangModule; }
- };
-
/// Return a descriptor for the corresponding module, if one exists.
virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
@@ -504,9 +479,8 @@ struct PointerLikeTypeTraits<
static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
- enum {
- NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
- };
+ static constexpr int NumLowBitsAvailable =
+ PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1;
};
} // namespace llvm
diff --git a/clang/include/clang/AST/GlobalDecl.h b/clang/include/clang/AST/GlobalDecl.h
index 145e961a23a3..d8ac498be54f 100644
--- a/clang/include/clang/AST/GlobalDecl.h
+++ b/clang/include/clang/AST/GlobalDecl.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_GLOBALDECL_H
#define LLVM_CLANG_AST_GLOBALDECL_H
+#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
@@ -33,17 +34,31 @@ enum class DynamicInitKind : unsigned {
AtExit,
};
+enum class KernelReferenceKind : unsigned {
+ Kernel = 0,
+ Stub = 1,
+};
+
/// GlobalDecl - represents a global declaration. This can either be a
/// CXXConstructorDecl and the constructor type (Base, Complete).
-/// a CXXDestructorDecl and the destructor type (Base, Complete) or
+/// a CXXDestructorDecl and the destructor type (Base, Complete),
+/// a FunctionDecl and the kernel reference type (Kernel, Stub), or
/// a VarDecl, a FunctionDecl or a BlockDecl.
+///
+/// When a new type of GlobalDecl is added, the following places should
+/// be updated to convert a Decl* to a GlobalDecl:
+/// PredefinedExpr::ComputeName() in lib/AST/Expr.cpp.
+/// getParentOfLocalEntity() in lib/AST/ItaniumMangle.cpp
+/// ASTNameGenerator::Implementation::writeFuncOrVarName in lib/AST/Mangle.cpp
+///
class GlobalDecl {
- llvm::PointerIntPair<const Decl *, 2> Value;
+ llvm::PointerIntPair<const Decl *, 3> Value;
unsigned MultiVersionIndex = 0;
void Init(const Decl *D) {
assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
+ assert(!D->hasAttr<CUDAGlobalAttr>() && "Use other ctor with GPU kernels!");
Value.setPointer(D);
}
@@ -53,8 +68,17 @@ public:
GlobalDecl(const VarDecl *D) { Init(D);}
GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
: MultiVersionIndex(MVIndex) {
- Init(D);
+ if (!D->hasAttr<CUDAGlobalAttr>()) {
+ Init(D);
+ return;
+ }
+ Value.setPointerAndInt(D, unsigned(getDefaultKernelReference(D)));
+ }
+ GlobalDecl(const FunctionDecl *D, KernelReferenceKind Kind)
+ : Value(D, unsigned(Kind)) {
+ assert(D->hasAttr<CUDAGlobalAttr>() && "Decl is not a GPU kernel!");
}
+ GlobalDecl(const NamedDecl *D) { Init(D); }
GlobalDecl(const BlockDecl *D) { Init(D); }
GlobalDecl(const CapturedDecl *D) { Init(D); }
GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
@@ -94,13 +118,22 @@ public:
}
unsigned getMultiVersionIndex() const {
- assert(isa<FunctionDecl>(getDecl()) &&
+ assert(isa<FunctionDecl>(
+ getDecl()) &&
+ !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
!isa<CXXConstructorDecl>(getDecl()) &&
!isa<CXXDestructorDecl>(getDecl()) &&
"Decl is not a plain FunctionDecl!");
return MultiVersionIndex;
}
+ KernelReferenceKind getKernelReferenceKind() const {
+ assert(isa<FunctionDecl>(getDecl()) &&
+ cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
+ "Decl is not a GPU kernel!");
+ return static_cast<KernelReferenceKind>(Value.getInt());
+ }
+
friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
return LHS.Value == RHS.Value &&
LHS.MultiVersionIndex == RHS.MultiVersionIndex;
@@ -108,12 +141,19 @@ public:
void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
+ explicit operator bool() const { return getAsOpaquePtr(); }
+
static GlobalDecl getFromOpaquePtr(void *P) {
GlobalDecl GD;
GD.Value.setFromOpaqueValue(P);
return GD;
}
+ static KernelReferenceKind getDefaultKernelReference(const FunctionDecl *D) {
+ return D->getLangOpts().CUDAIsDevice ? KernelReferenceKind::Kernel
+ : KernelReferenceKind::Stub;
+ }
+
GlobalDecl getWithDecl(const Decl *D) {
GlobalDecl Result(*this);
Result.Value.setPointer(D);
@@ -136,6 +176,7 @@ public:
GlobalDecl getWithMultiVersionIndex(unsigned Index) {
assert(isa<FunctionDecl>(getDecl()) &&
+ !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
!isa<CXXConstructorDecl>(getDecl()) &&
!isa<CXXDestructorDecl>(getDecl()) &&
"Decl is not a plain FunctionDecl!");
@@ -143,6 +184,15 @@ public:
Result.MultiVersionIndex = Index;
return Result;
}
+
+ GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind) {
+ assert(isa<FunctionDecl>(getDecl()) &&
+ cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
+ "Decl is not a GPU kernel!");
+ GlobalDecl Result(*this);
+ Result.Value.setInt(unsigned(Kind));
+ return Result;
+ }
};
} // namespace clang
diff --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h
index 4023e023e9d5..4e7162992418 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -23,10 +23,13 @@
#include "clang/AST/CommentVisitor.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/Mangle.h"
+#include "clang/AST/Type.h"
#include "llvm/Support/JSON.h"
namespace clang {
+class APValue;
+
class NodeStreamer {
bool FirstChild = true;
bool TopLevel = true;
@@ -64,7 +67,7 @@ public:
// We need to capture an owning-string in the lambda because the lambda
// is invoked in a deferred manner.
- std::string LabelStr = !Label.empty() ? Label : "inner";
+ std::string LabelStr(!Label.empty() ? Label : "inner");
bool WasFirstChild = FirstChild;
auto DumpWithIndent = [=](bool IsLastChild) {
if (WasFirstChild) {
@@ -201,6 +204,7 @@ public:
void Visit(const OMPClause *C);
void Visit(const BlockDecl::Capture &C);
void Visit(const GenericSelectionExpr::ConstAssociation &A);
+ void Visit(const APValue &Value, QualType Ty);
void VisitTypedefType(const TypedefType *TT);
void VisitFunctionType(const FunctionType *T);
diff --git a/clang/include/clang/AST/LocInfoType.h b/clang/include/clang/AST/LocInfoType.h
index 1073174bcf91..7e845ad03587 100644
--- a/clang/include/clang/AST/LocInfoType.h
+++ b/clang/include/clang/AST/LocInfoType.h
@@ -35,10 +35,7 @@ class LocInfoType : public Type {
TypeSourceInfo *DeclInfo;
LocInfoType(QualType ty, TypeSourceInfo *TInfo)
- : Type((TypeClass)LocInfo, ty, ty->isDependentType(),
- ty->isInstantiationDependentType(), ty->isVariablyModifiedType(),
- ty->containsUnexpandedParameterPack()),
- DeclInfo(TInfo) {
+ : Type((TypeClass)LocInfo, ty, ty->getDependence()), DeclInfo(TInfo) {
assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?");
}
friend class Sema;
diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h
index 5db5c5b977da..011d1faab8ea 100644
--- a/clang/include/clang/AST/Mangle.h
+++ b/clang/include/clang/AST/Mangle.h
@@ -14,6 +14,7 @@
#define LLVM_CLANG_AST_MANGLE_H
#include "clang/AST/Decl.h"
+#include "clang/AST/GlobalDecl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
@@ -96,8 +97,8 @@ public:
virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
// FIXME: consider replacing raw_ostream & with something like SmallString &.
- void mangleName(const NamedDecl *D, raw_ostream &);
- virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
+ void mangleName(GlobalDecl GD, raw_ostream &);
+ virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;
virtual void mangleThunk(const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
raw_ostream &) = 0;
@@ -109,11 +110,8 @@ public:
raw_ostream &) = 0;
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
- virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
- raw_ostream &) = 0;
- virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
- raw_ostream &) = 0;
virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
+ virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
void mangleGlobalBlock(const BlockDecl *BD,
const NamedDecl *ID,
@@ -151,9 +149,14 @@ public:
};
class ItaniumMangleContext : public MangleContext {
+ bool IsUniqueNameMangler = false;
public:
explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
: MangleContext(C, D, MK_Itanium) {}
+ explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D,
+ bool IsUniqueNameMangler)
+ : MangleContext(C, D, MK_Itanium),
+ IsUniqueNameMangler(IsUniqueNameMangler) {}
virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
@@ -172,12 +175,17 @@ public:
virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
+ virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
+
+ bool isUniqueNameMangler() { return IsUniqueNameMangler; }
+
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Itanium;
}
static ItaniumMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
+ DiagnosticsEngine &Diags,
+ bool IsUniqueNameMangler = false);
};
class MicrosoftMangleContext : public MangleContext {
diff --git a/clang/include/clang/AST/NestedNameSpecifier.h b/clang/include/clang/AST/NestedNameSpecifier.h
index c6fae6f465ff..540ac3df48fe 100644
--- a/clang/include/clang/AST/NestedNameSpecifier.h
+++ b/clang/include/clang/AST/NestedNameSpecifier.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
+#include "clang/AST/DependenceFlags.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/FoldingSet.h"
@@ -199,6 +200,8 @@ public:
return nullptr;
}
+ NestedNameSpecifierDependence getDependence() const;
+
/// Whether this nested name specifier refers to a dependent
/// type or not.
bool isDependent() const;
@@ -211,6 +214,9 @@ public:
/// parameter pack (for C++11 variadic templates).
bool containsUnexpandedParameterPack() const;
+ /// Whether this nested name specifier contains an error.
+ bool containsErrors() const;
+
/// Print this nested name specifier to the given output stream. If
/// `ResolveTemplateArguments` is true, we'll print actual types, e.g.
/// `ns::SomeTemplate<int, MyClass>` instead of
diff --git a/clang/include/clang/AST/NonTrivialTypeVisitor.h b/clang/include/clang/AST/NonTrivialTypeVisitor.h
index aafcedb9d10b..c95516538ad1 100644
--- a/clang/include/clang/AST/NonTrivialTypeVisitor.h
+++ b/clang/include/clang/AST/NonTrivialTypeVisitor.h
@@ -1,4 +1,4 @@
-//===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- C++ --*-===//
+//===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/clang/include/clang/AST/ODRHash.h b/clang/include/clang/AST/ODRHash.h
index cd4a6f37f5db..2e8593e0b835 100644
--- a/clang/include/clang/AST/ODRHash.h
+++ b/clang/include/clang/AST/ODRHash.h
@@ -89,7 +89,7 @@ public:
// Save booleans until the end to lower the size of data to process.
void AddBoolean(bool value);
- static bool isWhitelistedDecl(const Decl* D, const DeclContext *Parent);
+ static bool isDeclToBeProcessed(const Decl* D, const DeclContext *Parent);
private:
void AddDeclarationNameImpl(DeclarationName Name);
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 26f8389f9cfa..6de7b6deb514 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -31,6 +31,7 @@
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
+#include "llvm/Frontend/OpenMP/OMPContext.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
@@ -284,12 +285,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Allocator(A) {}
+ : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Allocator(A) {}
/// Build an empty clause.
OMPAllocatorClause()
- : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(),
+ SourceLocation()) {}
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -314,7 +316,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_allocator;
+ return T->getClauseKind() == llvm::omp::OMPC_allocator;
}
};
@@ -349,17 +351,17 @@ class OMPAllocateClause final
OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
Expr *Allocator, SourceLocation ColonLoc,
SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPAllocateClause>(OMPC_allocate, StartLoc, LParenLoc,
- EndLoc, N),
+ : OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, StartLoc,
+ LParenLoc, EndLoc, N),
Allocator(Allocator), ColonLoc(ColonLoc) {}
/// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPAllocateClause(unsigned N)
- : OMPVarListClause<OMPAllocateClause>(OMPC_allocate, SourceLocation(),
+ : OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate,
SourceLocation(), SourceLocation(),
- N) {}
+ SourceLocation(), N) {}
/// Sets location of ':' symbol in clause.
void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
@@ -411,7 +413,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_allocate;
+ return T->getClauseKind() == llvm::omp::OMPC_allocate;
}
};
@@ -469,15 +471,16 @@ public:
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation NameModifierLoc,
SourceLocation ColonLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this),
- LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc),
- NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) {
+ : OMPClause(llvm::omp::OMPC_if, StartLoc, EndLoc),
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond),
+ ColonLoc(ColonLoc), NameModifier(NameModifier),
+ NameModifierLoc(NameModifierLoc) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
OMPIfClause()
- : OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_if, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
@@ -511,7 +514,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_if;
+ return T->getClauseKind() == llvm::omp::OMPC_if;
}
};
@@ -547,14 +550,14 @@ public:
OMPFinalClause(Expr *Cond, Stmt *HelperCond,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_final, StartLoc, EndLoc), OMPClauseWithPreInit(this),
- LParenLoc(LParenLoc), Condition(Cond) {
+ : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc),
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
OMPFinalClause()
- : OMPClause(OMPC_final, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
@@ -579,7 +582,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_final;
+ return T->getClauseKind() == llvm::omp::OMPC_final;
}
};
@@ -617,7 +620,7 @@ public:
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_num_threads, StartLoc, EndLoc),
+ : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc),
OMPClauseWithPreInit(this), LParenLoc(LParenLoc),
NumThreads(NumThreads) {
setPreInitStmt(HelperNumThreads, CaptureRegion);
@@ -625,7 +628,8 @@ public:
/// Build an empty clause.
OMPNumThreadsClause()
- : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(),
+ SourceLocation()),
OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
@@ -651,7 +655,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_num_threads;
+ return T->getClauseKind() == llvm::omp::OMPC_num_threads;
}
};
@@ -687,12 +691,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Safelen(Len) {}
+ : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Safelen(Len) {}
/// Build an empty clause.
explicit OMPSafelenClause()
- : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) {
+ }
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -717,7 +722,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_safelen;
+ return T->getClauseKind() == llvm::omp::OMPC_safelen;
}
};
@@ -752,12 +757,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Simdlen(Len) {}
+ : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Simdlen(Len) {}
/// Build an empty clause.
explicit OMPSimdlenClause()
- : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) {
+ }
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -782,7 +788,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_simdlen;
+ return T->getClauseKind() == llvm::omp::OMPC_simdlen;
}
};
@@ -818,12 +824,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumForLoops(Num) {}
+ : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), NumForLoops(Num) {}
/// Build an empty clause.
explicit OMPCollapseClause()
- : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(),
+ SourceLocation()) {}
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -848,7 +855,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_collapse;
+ return T->getClauseKind() == llvm::omp::OMPC_collapse;
}
};
@@ -866,7 +873,7 @@ class OMPDefaultClause : public OMPClause {
SourceLocation LParenLoc;
/// A kind of the 'default' clause.
- OpenMPDefaultClauseKind Kind = OMPC_DEFAULT_unknown;
+ llvm::omp::DefaultKind Kind = llvm::omp::OMP_DEFAULT_unknown;
/// Start location of the kind in source code.
SourceLocation KindKwLoc;
@@ -874,7 +881,7 @@ class OMPDefaultClause : public OMPClause {
/// Set kind of the clauses.
///
/// \param K Argument of clause.
- void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
+ void setDefaultKind(llvm::omp::DefaultKind K) { Kind = K; }
/// Set argument location.
///
@@ -889,15 +896,16 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
+ OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Kind(A), KindKwLoc(ALoc) {}
+ : OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
/// Build an empty clause.
OMPDefaultClause()
- : OMPClause(OMPC_default, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_default, SourceLocation(), SourceLocation()) {
+ }
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -906,7 +914,7 @@ public:
SourceLocation getLParenLoc() const { return LParenLoc; }
/// Returns kind of the clause.
- OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
+ llvm::omp::DefaultKind getDefaultKind() const { return Kind; }
/// Returns location of clause kind.
SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
@@ -927,7 +935,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_default;
+ return T->getClauseKind() == llvm::omp::OMPC_default;
}
};
@@ -973,12 +981,13 @@ public:
OMPProcBindClause(llvm::omp::ProcBindKind A, SourceLocation ALoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Kind(A), KindKwLoc(ALoc) {}
+ : OMPClause(llvm::omp::OMPC_proc_bind, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
/// Build an empty clause.
OMPProcBindClause()
- : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_proc_bind, SourceLocation(),
+ SourceLocation()) {}
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -1008,7 +1017,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_proc_bind;
+ return T->getClauseKind() == llvm::omp::OMPC_proc_bind;
}
};
@@ -1028,11 +1037,12 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_unified_address, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPUnifiedAddressClause()
- : OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(),
+ SourceLocation()) {}
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1050,7 +1060,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_unified_address;
+ return T->getClauseKind() == llvm::omp::OMPC_unified_address;
}
};
@@ -1070,11 +1080,12 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_unified_shared_memory, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_unified_shared_memory, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPUnifiedSharedMemoryClause()
- : OMPClause(OMPC_unified_shared_memory, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_unified_shared_memory, SourceLocation(),
+ SourceLocation()) {}
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1092,7 +1103,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_unified_shared_memory;
+ return T->getClauseKind() == llvm::omp::OMPC_unified_shared_memory;
}
};
@@ -1112,11 +1123,12 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_reverse_offload, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_reverse_offload, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPReverseOffloadClause()
- : OMPClause(OMPC_reverse_offload, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_reverse_offload, SourceLocation(),
+ SourceLocation()) {}
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1134,7 +1146,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_reverse_offload;
+ return T->getClauseKind() == llvm::omp::OMPC_reverse_offload;
}
};
@@ -1154,12 +1166,12 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_dynamic_allocators, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_dynamic_allocators, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPDynamicAllocatorsClause()
- : OMPClause(OMPC_dynamic_allocators, SourceLocation(), SourceLocation()) {
- }
+ : OMPClause(llvm::omp::OMPC_dynamic_allocators, SourceLocation(),
+ SourceLocation()) {}
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1177,7 +1189,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_dynamic_allocators;
+ return T->getClauseKind() == llvm::omp::OMPC_dynamic_allocators;
}
};
@@ -1229,12 +1241,12 @@ public:
SourceLocation ALoc, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_atomic_default_mem_order, StartLoc, EndLoc),
+ : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, StartLoc, EndLoc),
LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
/// Build an empty clause.
OMPAtomicDefaultMemOrderClause()
- : OMPClause(OMPC_atomic_default_mem_order, SourceLocation(),
+ : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, SourceLocation(),
SourceLocation()) {}
/// Sets the location of '('.
@@ -1267,7 +1279,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_atomic_default_mem_order;
+ return T->getClauseKind() == llvm::omp::OMPC_atomic_default_mem_order;
}
};
@@ -1386,9 +1398,9 @@ public:
Expr *ChunkSize, Stmt *HelperChunkSize,
OpenMPScheduleClauseModifier M1, SourceLocation M1Loc,
OpenMPScheduleClauseModifier M2, SourceLocation M2Loc)
- : OMPClause(OMPC_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this),
- LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc),
- ChunkSize(ChunkSize) {
+ : OMPClause(llvm::omp::OMPC_schedule, StartLoc, EndLoc),
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind),
+ KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) {
setPreInitStmt(HelperChunkSize);
Modifiers[FIRST] = M1;
Modifiers[SECOND] = M2;
@@ -1398,7 +1410,7 @@ public:
/// Build an empty clause.
explicit OMPScheduleClause()
- : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_schedule, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {
Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown;
Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown;
@@ -1460,7 +1472,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_schedule;
+ return T->getClauseKind() == llvm::omp::OMPC_schedule;
}
};
@@ -1495,12 +1507,12 @@ class OMPOrderedClause final
/// \param EndLoc Ending location of the clause.
OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumForLoops(Num), NumberOfLoops(NumLoops) {}
+ : OMPClause(llvm::omp::OMPC_ordered, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), NumForLoops(Num), NumberOfLoops(NumLoops) {}
/// Build an empty clause.
explicit OMPOrderedClause(unsigned NumLoops)
- : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_ordered, SourceLocation(), SourceLocation()),
NumberOfLoops(NumLoops) {}
/// Set the number of associated for-loops.
@@ -1556,7 +1568,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_ordered;
+ return T->getClauseKind() == llvm::omp::OMPC_ordered;
}
};
@@ -1573,11 +1585,11 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_nowait, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPNowaitClause()
- : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {}
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1595,7 +1607,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_nowait;
+ return T->getClauseKind() == llvm::omp::OMPC_nowait;
}
};
@@ -1612,11 +1624,11 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_untied, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_untied, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPUntiedClause()
- : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_untied, SourceLocation(), SourceLocation()) {}
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1634,7 +1646,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_untied;
+ return T->getClauseKind() == llvm::omp::OMPC_untied;
}
};
@@ -1652,11 +1664,12 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_mergeable, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPMergeableClause()
- : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_mergeable, SourceLocation(),
+ SourceLocation()) {}
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1674,7 +1687,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_mergeable;
+ return T->getClauseKind() == llvm::omp::OMPC_mergeable;
}
};
@@ -1691,10 +1704,11 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_read, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_read, StartLoc, EndLoc) {}
/// Build an empty clause.
- OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {}
+ OMPReadClause()
+ : OMPClause(llvm::omp::OMPC_read, SourceLocation(), SourceLocation()) {}
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1712,7 +1726,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_read;
+ return T->getClauseKind() == llvm::omp::OMPC_read;
}
};
@@ -1729,11 +1743,11 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_write, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_write, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPWriteClause()
- : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_write, SourceLocation(), SourceLocation()) {}
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1751,7 +1765,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_write;
+ return T->getClauseKind() == llvm::omp::OMPC_write;
}
};
@@ -1762,18 +1776,95 @@ public:
/// #pragma omp atomic update
/// \endcode
/// In this example directive '#pragma omp atomic' has 'update' clause.
-class OMPUpdateClause : public OMPClause {
-public:
+/// Also, this class represents 'update' clause in '#pragma omp depobj'
+/// directive.
+///
+/// \code
+/// #pragma omp depobj(a) update(in)
+/// \endcode
+/// In this example directive '#pragma omp depobj' has 'update' clause with 'in'
+/// dependence kind.
+class OMPUpdateClause final
+ : public OMPClause,
+ private llvm::TrailingObjects<OMPUpdateClause, SourceLocation,
+ OpenMPDependClauseKind> {
+ friend class OMPClauseReader;
+ friend TrailingObjects;
+
+ /// true if extended version of the clause for 'depobj' directive.
+ bool IsExtended = false;
+
+ /// Define the sizes of each trailing object array except the last one. This
+ /// is required for TrailingObjects to work properly.
+ size_t numTrailingObjects(OverloadToken<SourceLocation>) const {
+ // 2 locations: for '(' and argument location.
+ return IsExtended ? 2 : 0;
+ }
+
+ /// Sets the the location of '(' in clause for 'depobj' directive.
+ void setLParenLoc(SourceLocation Loc) {
+ assert(IsExtended && "Expected extended clause.");
+ *getTrailingObjects<SourceLocation>() = Loc;
+ }
+
+ /// Sets the the location of '(' in clause for 'depobj' directive.
+ void setArgumentLoc(SourceLocation Loc) {
+ assert(IsExtended && "Expected extended clause.");
+ *std::next(getTrailingObjects<SourceLocation>(), 1) = Loc;
+ }
+
+ /// Sets the dependence kind for the clause for 'depobj' directive.
+ void setDependencyKind(OpenMPDependClauseKind DK) {
+ assert(IsExtended && "Expected extended clause.");
+ *getTrailingObjects<OpenMPDependClauseKind>() = DK;
+ }
+
/// Build 'update' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_update, StartLoc, EndLoc) {}
+ OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc,
+ bool IsExtended)
+ : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc),
+ IsExtended(IsExtended) {}
/// Build an empty clause.
- OMPUpdateClause()
- : OMPClause(OMPC_update, SourceLocation(), SourceLocation()) {}
+ OMPUpdateClause(bool IsExtended)
+ : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()),
+ IsExtended(IsExtended) {}
+
+public:
+ /// Creates clause for 'atomic' directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc);
+
+ /// Creates clause for 'depobj' directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ArgumentLoc Location of the argument.
+ /// \param DK Dependence kind.
+ /// \param EndLoc Ending location of the clause.
+ static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ArgumentLoc,
+ OpenMPDependClauseKind DK,
+ SourceLocation EndLoc);
+
+ /// Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param IsExtended true if extended clause for 'depobj' directive must be
+ /// created.
+ static OMPUpdateClause *CreateEmpty(const ASTContext &C, bool IsExtended);
+
+ /// Checks if the clause is the extended clauses for 'depobj' directive.
+ bool isExtended() const { return IsExtended; }
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1790,8 +1881,26 @@ public:
return const_child_range(const_child_iterator(), const_child_iterator());
}
+ /// Gets the the location of '(' in clause for 'depobj' directive.
+ SourceLocation getLParenLoc() const {
+ assert(IsExtended && "Expected extended clause.");
+ return *getTrailingObjects<SourceLocation>();
+ }
+
+ /// Gets the the location of argument in clause for 'depobj' directive.
+ SourceLocation getArgumentLoc() const {
+ assert(IsExtended && "Expected extended clause.");
+ return *std::next(getTrailingObjects<SourceLocation>(), 1);
+ }
+
+ /// Gets the dependence kind in clause for 'depobj' directive.
+ OpenMPDependClauseKind getDependencyKind() const {
+ assert(IsExtended && "Expected extended clause.");
+ return *getTrailingObjects<OpenMPDependClauseKind>();
+ }
+
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_update;
+ return T->getClauseKind() == llvm::omp::OMPC_update;
}
};
@@ -1809,11 +1918,12 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_capture, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_capture, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPCaptureClause()
- : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_capture, SourceLocation(), SourceLocation()) {
+ }
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1831,7 +1941,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_capture;
+ return T->getClauseKind() == llvm::omp::OMPC_capture;
}
};
@@ -1849,11 +1959,12 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_seq_cst, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPSeqCstClause()
- : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_seq_cst, SourceLocation(), SourceLocation()) {
+ }
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -1871,7 +1982,171 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_seq_cst;
+ return T->getClauseKind() == llvm::omp::OMPC_seq_cst;
+ }
+};
+
+/// This represents 'acq_rel' clause in the '#pragma omp atomic|flush'
+/// directives.
+///
+/// \code
+/// #pragma omp flush acq_rel
+/// \endcode
+/// In this example directive '#pragma omp flush' has 'acq_rel' clause.
+class OMPAcqRelClause final : public OMPClause {
+public:
+ /// Build 'ack_rel' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_acq_rel, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPAcqRelClause()
+ : OMPClause(llvm::omp::OMPC_acq_rel, SourceLocation(), SourceLocation()) {
+ }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_acq_rel;
+ }
+};
+
+/// This represents 'acquire' clause in the '#pragma omp atomic|flush'
+/// directives.
+///
+/// \code
+/// #pragma omp flush acquire
+/// \endcode
+/// In this example directive '#pragma omp flush' has 'acquire' clause.
+class OMPAcquireClause final : public OMPClause {
+public:
+ /// Build 'acquire' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_acquire, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPAcquireClause()
+ : OMPClause(llvm::omp::OMPC_acquire, SourceLocation(), SourceLocation()) {
+ }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_acquire;
+ }
+};
+
+/// This represents 'release' clause in the '#pragma omp atomic|flush'
+/// directives.
+///
+/// \code
+/// #pragma omp flush release
+/// \endcode
+/// In this example directive '#pragma omp flush' has 'release' clause.
+class OMPReleaseClause final : public OMPClause {
+public:
+ /// Build 'release' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_release, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPReleaseClause()
+ : OMPClause(llvm::omp::OMPC_release, SourceLocation(), SourceLocation()) {
+ }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_release;
+ }
+};
+
+/// This represents 'relaxed' clause in the '#pragma omp atomic'
+/// directives.
+///
+/// \code
+/// #pragma omp atomic relaxed
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'relaxed' clause.
+class OMPRelaxedClause final : public OMPClause {
+public:
+ /// Build 'relaxed' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_relaxed, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPRelaxedClause()
+ : OMPClause(llvm::omp::OMPC_relaxed, SourceLocation(), SourceLocation()) {
+ }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_relaxed;
}
};
@@ -1897,16 +2172,16 @@ class OMPPrivateClause final
/// \param N Number of the variables in the clause.
OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc,
- EndLoc, N) {}
+ : OMPVarListClause<OMPPrivateClause>(llvm::omp::OMPC_private, StartLoc,
+ LParenLoc, EndLoc, N) {}
/// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPPrivateClause(unsigned N)
- : OMPVarListClause<OMPPrivateClause>(OMPC_private, SourceLocation(),
+ : OMPVarListClause<OMPPrivateClause>(llvm::omp::OMPC_private,
SourceLocation(), SourceLocation(),
- N) {}
+ SourceLocation(), N) {}
/// Sets the list of references to private copies with initializers for
/// new private variables.
@@ -1976,7 +2251,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_private;
+ return T->getClauseKind() == llvm::omp::OMPC_private;
}
};
@@ -2004,8 +2279,8 @@ class OMPFirstprivateClause final
/// \param N Number of the variables in the clause.
OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc,
- LParenLoc, EndLoc, N),
+ : OMPVarListClause<OMPFirstprivateClause>(llvm::omp::OMPC_firstprivate,
+ StartLoc, LParenLoc, EndLoc, N),
OMPClauseWithPreInit(this) {}
/// Build an empty clause.
@@ -2013,7 +2288,7 @@ class OMPFirstprivateClause final
/// \param N Number of variables.
explicit OMPFirstprivateClause(unsigned N)
: OMPVarListClause<OMPFirstprivateClause>(
- OMPC_firstprivate, SourceLocation(), SourceLocation(),
+ llvm::omp::OMPC_firstprivate, SourceLocation(), SourceLocation(),
SourceLocation(), N),
OMPClauseWithPreInit(this) {}
@@ -2117,7 +2392,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_firstprivate;
+ return T->getClauseKind() == llvm::omp::OMPC_firstprivate;
}
};
@@ -2170,8 +2445,8 @@ class OMPLastprivateClause final
SourceLocation EndLoc, OpenMPLastprivateModifier LPKind,
SourceLocation LPKindLoc, SourceLocation ColonLoc,
unsigned N)
- : OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc,
- LParenLoc, EndLoc, N),
+ : OMPVarListClause<OMPLastprivateClause>(llvm::omp::OMPC_lastprivate,
+ StartLoc, LParenLoc, EndLoc, N),
OMPClauseWithPostUpdate(this), LPKind(LPKind), LPKindLoc(LPKindLoc),
ColonLoc(ColonLoc) {}
@@ -2180,7 +2455,7 @@ class OMPLastprivateClause final
/// \param N Number of variables.
explicit OMPLastprivateClause(unsigned N)
: OMPVarListClause<OMPLastprivateClause>(
- OMPC_lastprivate, SourceLocation(), SourceLocation(),
+ llvm::omp::OMPC_lastprivate, SourceLocation(), SourceLocation(),
SourceLocation(), N),
OMPClauseWithPostUpdate(this) {}
@@ -2356,7 +2631,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_lastprivate;
+ return T->getClauseKind() == llvm::omp::OMPC_lastprivate;
}
};
@@ -2381,16 +2656,16 @@ class OMPSharedClause final
/// \param N Number of the variables in the clause.
OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc,
- EndLoc, N) {}
+ : OMPVarListClause<OMPSharedClause>(llvm::omp::OMPC_shared, StartLoc,
+ LParenLoc, EndLoc, N) {}
/// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPSharedClause(unsigned N)
- : OMPVarListClause<OMPSharedClause>(OMPC_shared, SourceLocation(),
+ : OMPVarListClause<OMPSharedClause>(llvm::omp::OMPC_shared,
SourceLocation(), SourceLocation(),
- N) {}
+ SourceLocation(), N) {}
public:
/// Creates clause with a list of variables \a VL.
@@ -2428,7 +2703,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_shared;
+ return T->getClauseKind() == llvm::omp::OMPC_shared;
}
};
@@ -2448,6 +2723,12 @@ class OMPReductionClause final
friend OMPVarListClause;
friend TrailingObjects;
+ /// Reduction modifier.
+ OpenMPReductionClauseModifier Modifier = OMPC_REDUCTION_unknown;
+
+ /// Reduction modifier location.
+ SourceLocation ModifierLoc;
+
/// Location of ':'.
SourceLocation ColonLoc;
@@ -2461,29 +2742,39 @@ class OMPReductionClause final
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
+ /// \param ModifierLoc Modifier location.
/// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
/// \param N Number of the variables in the clause.
/// \param QualifierLoc The nested-name qualifier with location information
/// \param NameInfo The full name info for reduction identifier.
OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N,
+ SourceLocation ModifierLoc, SourceLocation ColonLoc,
+ SourceLocation EndLoc,
+ OpenMPReductionClauseModifier Modifier, unsigned N,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo)
- : OMPVarListClause<OMPReductionClause>(OMPC_reduction, StartLoc,
- LParenLoc, EndLoc, N),
- OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc),
+ : OMPVarListClause<OMPReductionClause>(llvm::omp::OMPC_reduction,
+ StartLoc, LParenLoc, EndLoc, N),
+ OMPClauseWithPostUpdate(this), Modifier(Modifier),
+ ModifierLoc(ModifierLoc), ColonLoc(ColonLoc),
QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
/// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPReductionClause(unsigned N)
- : OMPVarListClause<OMPReductionClause>(OMPC_reduction, SourceLocation(),
+ : OMPVarListClause<OMPReductionClause>(llvm::omp::OMPC_reduction,
SourceLocation(), SourceLocation(),
- N),
+ SourceLocation(), N),
OMPClauseWithPostUpdate(this) {}
+ /// Sets reduction modifier.
+ void setModifier(OpenMPReductionClauseModifier M) { Modifier = M; }
+
+ /// Sets location of the modifier.
+ void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }
+
/// Sets location of ':' symbol in clause.
void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
@@ -2548,11 +2839,47 @@ class OMPReductionClause final
return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
}
+ /// Set list of helper copy operations for inscan reductions.
+ /// The form is: Temps[i] = LHS[i];
+ void setInscanCopyOps(ArrayRef<Expr *> Ops);
+
+ /// Get the list of helper inscan copy operations.
+ MutableArrayRef<Expr *> getInscanCopyOps() {
+ return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getInscanCopyOps() const {
+ return llvm::makeArrayRef(getReductionOps().end(), varlist_size());
+ }
+
+ /// Set list of helper temp vars for inscan copy array operations.
+ void setInscanCopyArrayTemps(ArrayRef<Expr *> CopyArrayTemps);
+
+ /// Get the list of helper inscan copy temps.
+ MutableArrayRef<Expr *> getInscanCopyArrayTemps() {
+ return MutableArrayRef<Expr *>(getInscanCopyOps().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getInscanCopyArrayTemps() const {
+ return llvm::makeArrayRef(getInscanCopyOps().end(), varlist_size());
+ }
+
+ /// Set list of helper temp elements vars for inscan copy array operations.
+ void setInscanCopyArrayElems(ArrayRef<Expr *> CopyArrayElems);
+
+ /// Get the list of helper inscan copy temps.
+ MutableArrayRef<Expr *> getInscanCopyArrayElems() {
+ return MutableArrayRef<Expr *>(getInscanCopyArrayTemps().end(),
+ varlist_size());
+ }
+ ArrayRef<const Expr *> getInscanCopyArrayElems() const {
+ return llvm::makeArrayRef(getInscanCopyArrayTemps().end(), varlist_size());
+ }
+
public:
/// Creates clause with a list of variables \a VL.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
+ /// \param ModifierLoc Modifier location.
/// \param ColonLoc Location of ':'.
/// \param EndLoc Ending location of the clause.
/// \param VL The variables in the clause.
@@ -2577,23 +2904,41 @@ public:
/// \endcode
/// Required for proper codegen of final reduction operation performed by the
/// reduction clause.
+ /// \param CopyOps List of copy operations for inscan reductions:
+ /// \code
+ /// TempExprs = LHSExprs;
+ /// \endcode
+ /// \param CopyArrayTemps Temp arrays for prefix sums.
+ /// \param CopyArrayElems Temp arrays for prefix sums.
/// \param PreInit Statement that must be executed before entering the OpenMP
/// region with this clause.
/// \param PostUpdate Expression that must be executed after exit from the
/// OpenMP region with this clause.
static OMPReductionClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
- NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation ModifierLoc, SourceLocation ColonLoc,
+ SourceLocation EndLoc, OpenMPReductionClauseModifier Modifier,
+ ArrayRef<Expr *> VL, NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates,
ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
- ArrayRef<Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate);
+ ArrayRef<Expr *> ReductionOps, ArrayRef<Expr *> CopyOps,
+ ArrayRef<Expr *> CopyArrayTemps, ArrayRef<Expr *> CopyArrayElems,
+ Stmt *PreInit, Expr *PostUpdate);
/// Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
- static OMPReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
+ /// \param Modifier Reduction modifier.
+ static OMPReductionClause *
+ CreateEmpty(const ASTContext &C, unsigned N,
+ OpenMPReductionClauseModifier Modifier);
+
+ /// Returns modifier.
+ OpenMPReductionClauseModifier getModifier() const { return Modifier; }
+
+ /// Returns modifier location.
+ SourceLocation getModifierLoc() const { return ModifierLoc; }
/// Gets location of ':' symbol in clause.
SourceLocation getColonLoc() const { return ColonLoc; }
@@ -2644,6 +2989,36 @@ public:
getReductionOps().end());
}
+ helper_expr_const_range copy_ops() const {
+ return helper_expr_const_range(getInscanCopyOps().begin(),
+ getInscanCopyOps().end());
+ }
+
+ helper_expr_range copy_ops() {
+ return helper_expr_range(getInscanCopyOps().begin(),
+ getInscanCopyOps().end());
+ }
+
+ helper_expr_const_range copy_array_temps() const {
+ return helper_expr_const_range(getInscanCopyArrayTemps().begin(),
+ getInscanCopyArrayTemps().end());
+ }
+
+ helper_expr_range copy_array_temps() {
+ return helper_expr_range(getInscanCopyArrayTemps().begin(),
+ getInscanCopyArrayTemps().end());
+ }
+
+ helper_expr_const_range copy_array_elems() const {
+ return helper_expr_const_range(getInscanCopyArrayElems().begin(),
+ getInscanCopyArrayElems().end());
+ }
+
+ helper_expr_range copy_array_elems() {
+ return helper_expr_range(getInscanCopyArrayElems().begin(),
+ getInscanCopyArrayElems().end());
+ }
+
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
@@ -2664,7 +3039,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_reduction;
+ return T->getClauseKind() == llvm::omp::OMPC_reduction;
}
};
@@ -2706,8 +3081,8 @@ class OMPTaskReductionClause final
SourceLocation ColonLoc, SourceLocation EndLoc,
unsigned N, NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo)
- : OMPVarListClause<OMPTaskReductionClause>(OMPC_task_reduction, StartLoc,
- LParenLoc, EndLoc, N),
+ : OMPVarListClause<OMPTaskReductionClause>(
+ llvm::omp::OMPC_task_reduction, StartLoc, LParenLoc, EndLoc, N),
OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc),
QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
@@ -2716,7 +3091,7 @@ class OMPTaskReductionClause final
/// \param N Number of variables.
explicit OMPTaskReductionClause(unsigned N)
: OMPVarListClause<OMPTaskReductionClause>(
- OMPC_task_reduction, SourceLocation(), SourceLocation(),
+ llvm::omp::OMPC_task_reduction, SourceLocation(), SourceLocation(),
SourceLocation(), N),
OMPClauseWithPostUpdate(this) {}
@@ -2896,7 +3271,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_task_reduction;
+ return T->getClauseKind() == llvm::omp::OMPC_task_reduction;
}
};
@@ -2937,8 +3312,8 @@ class OMPInReductionClause final
SourceLocation ColonLoc, SourceLocation EndLoc,
unsigned N, NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo)
- : OMPVarListClause<OMPInReductionClause>(OMPC_in_reduction, StartLoc,
- LParenLoc, EndLoc, N),
+ : OMPVarListClause<OMPInReductionClause>(llvm::omp::OMPC_in_reduction,
+ StartLoc, LParenLoc, EndLoc, N),
OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc),
QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
@@ -2947,7 +3322,7 @@ class OMPInReductionClause final
/// \param N Number of variables.
explicit OMPInReductionClause(unsigned N)
: OMPVarListClause<OMPInReductionClause>(
- OMPC_in_reduction, SourceLocation(), SourceLocation(),
+ llvm::omp::OMPC_in_reduction, SourceLocation(), SourceLocation(),
SourceLocation(), N),
OMPClauseWithPostUpdate(this) {}
@@ -3151,7 +3526,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_in_reduction;
+ return T->getClauseKind() == llvm::omp::OMPC_in_reduction;
}
};
@@ -3197,8 +3572,8 @@ class OMPLinearClause final
OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
SourceLocation ColonLoc, SourceLocation EndLoc,
unsigned NumVars)
- : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc,
- EndLoc, NumVars),
+ : OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear, StartLoc,
+ LParenLoc, EndLoc, NumVars),
OMPClauseWithPostUpdate(this), Modifier(Modifier),
ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {}
@@ -3206,9 +3581,9 @@ class OMPLinearClause final
///
/// \param NumVars Number of variables.
explicit OMPLinearClause(unsigned NumVars)
- : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(),
+ : OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear,
SourceLocation(), SourceLocation(),
- NumVars),
+ SourceLocation(), NumVars),
OMPClauseWithPostUpdate(this) {}
/// Gets the list of initial values for linear variables.
@@ -3428,7 +3803,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_linear;
+ return T->getClauseKind() == llvm::omp::OMPC_linear;
}
};
@@ -3463,17 +3838,17 @@ class OMPAlignedClause final
OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc,
unsigned NumVars)
- : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, StartLoc, LParenLoc,
- EndLoc, NumVars),
+ : OMPVarListClause<OMPAlignedClause>(llvm::omp::OMPC_aligned, StartLoc,
+ LParenLoc, EndLoc, NumVars),
ColonLoc(ColonLoc) {}
/// Build an empty clause.
///
/// \param NumVars Number of variables.
explicit OMPAlignedClause(unsigned NumVars)
- : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(),
+ : OMPVarListClause<OMPAlignedClause>(llvm::omp::OMPC_aligned,
SourceLocation(), SourceLocation(),
- NumVars) {}
+ SourceLocation(), NumVars) {}
public:
/// Creates clause with a list of variables \a VL and alignment \a A.
@@ -3527,7 +3902,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_aligned;
+ return T->getClauseKind() == llvm::omp::OMPC_aligned;
}
};
@@ -3566,16 +3941,16 @@ class OMPCopyinClause final
/// \param N Number of the variables in the clause.
OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc,
- EndLoc, N) {}
+ : OMPVarListClause<OMPCopyinClause>(llvm::omp::OMPC_copyin, StartLoc,
+ LParenLoc, EndLoc, N) {}
/// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPCopyinClause(unsigned N)
- : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, SourceLocation(),
+ : OMPVarListClause<OMPCopyinClause>(llvm::omp::OMPC_copyin,
SourceLocation(), SourceLocation(),
- N) {}
+ SourceLocation(), N) {}
/// Set list of helper expressions, required for proper codegen of the
/// clause. These expressions represent source expression in the final
@@ -3703,7 +4078,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_copyin;
+ return T->getClauseKind() == llvm::omp::OMPC_copyin;
}
};
@@ -3730,15 +4105,16 @@ class OMPCopyprivateClause final
/// \param N Number of the variables in the clause.
OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc,
- LParenLoc, EndLoc, N) {}
+ : OMPVarListClause<OMPCopyprivateClause>(llvm::omp::OMPC_copyprivate,
+ StartLoc, LParenLoc, EndLoc, N) {
+ }
/// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPCopyprivateClause(unsigned N)
: OMPVarListClause<OMPCopyprivateClause>(
- OMPC_copyprivate, SourceLocation(), SourceLocation(),
+ llvm::omp::OMPC_copyprivate, SourceLocation(), SourceLocation(),
SourceLocation(), N) {}
/// Set list of helper expressions, required for proper codegen of the
@@ -3866,7 +4242,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_copyprivate;
+ return T->getClauseKind() == llvm::omp::OMPC_copyprivate;
}
};
@@ -3896,16 +4272,16 @@ class OMPFlushClause final
/// \param N Number of the variables in the clause.
OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
- EndLoc, N) {}
+ : OMPVarListClause<OMPFlushClause>(llvm::omp::OMPC_flush, StartLoc,
+ LParenLoc, EndLoc, N) {}
/// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPFlushClause(unsigned N)
- : OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(),
+ : OMPVarListClause<OMPFlushClause>(llvm::omp::OMPC_flush,
SourceLocation(), SourceLocation(),
- N) {}
+ SourceLocation(), N) {}
public:
/// Creates clause with a list of variables \a VL.
@@ -3943,7 +4319,94 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_flush;
+ return T->getClauseKind() == llvm::omp::OMPC_flush;
+ }
+};
+
+/// This represents implicit clause 'depobj' for the '#pragma omp depobj'
+/// directive.
+/// This clause does not exist by itself, it can be only as a part of 'omp
+/// depobj' directive. This clause is introduced to keep the original structure
+/// of \a OMPExecutableDirective class and its derivatives and to use the
+/// existing infrastructure of clauses with the list of variables.
+///
+/// \code
+/// #pragma omp depobj(a) destroy
+/// \endcode
+/// In this example directive '#pragma omp depobj' has implicit clause 'depobj'
+/// with the depobj 'a'.
+class OMPDepobjClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// Chunk size.
+ Expr *Depobj = nullptr;
+
+ /// Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPDepobjClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_depobj, StartLoc, EndLoc),
+ LParenLoc(LParenLoc) {}
+
+ /// Build an empty clause.
+ ///
+ explicit OMPDepobjClause()
+ : OMPClause(llvm::omp::OMPC_depobj, SourceLocation(), SourceLocation()) {}
+
+ void setDepobj(Expr *E) { Depobj = E; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+ /// Creates clause.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param Depobj depobj expression associated with the 'depobj' directive.
+ static OMPDepobjClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, Expr *Depobj);
+
+ /// Creates an empty clause.
+ ///
+ /// \param C AST context.
+ static OMPDepobjClause *CreateEmpty(const ASTContext &C);
+
+ /// Returns depobj expression associated with the clause.
+ Expr *getDepobj() { return Depobj; }
+ const Expr *getDepobj() const { return Depobj; }
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(&Depobj),
+ reinterpret_cast<Stmt **>(&Depobj) + 1);
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<OMPDepobjClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_depobj;
}
};
@@ -3984,8 +4447,9 @@ class OMPDependClause final
/// clause.
OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N, unsigned NumLoops)
- : OMPVarListClause<OMPDependClause>(OMPC_depend, StartLoc, LParenLoc,
- EndLoc, N), NumLoops(NumLoops) {}
+ : OMPVarListClause<OMPDependClause>(llvm::omp::OMPC_depend, StartLoc,
+ LParenLoc, EndLoc, N),
+ NumLoops(NumLoops) {}
/// Build an empty clause.
///
@@ -3993,9 +4457,9 @@ class OMPDependClause final
/// \param NumLoops Number of loops that is associated with this depend
/// clause.
explicit OMPDependClause(unsigned N, unsigned NumLoops)
- : OMPVarListClause<OMPDependClause>(OMPC_depend, SourceLocation(),
+ : OMPVarListClause<OMPDependClause>(llvm::omp::OMPC_depend,
SourceLocation(), SourceLocation(),
- N),
+ SourceLocation(), N),
NumLoops(NumLoops) {}
/// Set dependency kind.
@@ -4007,6 +4471,9 @@ class OMPDependClause final
/// Set colon location.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ /// Sets optional dependency modifier.
+ void setModifier(Expr *DepModifier);
+
public:
/// Creates clause with a list of variables \a VL.
///
@@ -4022,7 +4489,7 @@ public:
/// clause.
static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc,
- SourceLocation EndLoc,
+ SourceLocation EndLoc, Expr *DepModifier,
OpenMPDependClauseKind DepKind,
SourceLocation DepLoc, SourceLocation ColonLoc,
ArrayRef<Expr *> VL, unsigned NumLoops);
@@ -4039,6 +4506,12 @@ public:
/// Get dependency type.
OpenMPDependClauseKind getDependencyKind() const { return DepKind; }
+ /// Return optional depend modifier.
+ Expr *getModifier();
+ const Expr *getModifier() const {
+ return const_cast<OMPDependClause *>(this)->getModifier();
+ }
+
/// Get dependency type location.
SourceLocation getDependencyLoc() const { return DepLoc; }
@@ -4074,7 +4547,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_depend;
+ return T->getClauseKind() == llvm::omp::OMPC_depend;
}
};
@@ -4092,6 +4565,12 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit {
/// Location of '('.
SourceLocation LParenLoc;
+ /// Device clause modifier.
+ OpenMPDeviceClauseModifier Modifier = OMPC_DEVICE_unknown;
+
+ /// Location of the modifier.
+ SourceLocation ModifierLoc;
+
/// Device number.
Stmt *Device = nullptr;
@@ -4100,26 +4579,36 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit {
/// \param E Device number.
void setDevice(Expr *E) { Device = E; }
+ /// Sets modifier.
+ void setModifier(OpenMPDeviceClauseModifier M) { Modifier = M; }
+
+ /// Setst modifier location.
+ void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }
+
public:
/// Build 'device' clause.
///
+ /// \param Modifier Clause modifier.
/// \param E Expression associated with this clause.
/// \param CaptureRegion Innermost OpenMP region where expressions in this
/// clause must be captured.
/// \param StartLoc Starting location of the clause.
+ /// \param ModifierLoc Modifier location.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- OMPDeviceClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion,
- SourceLocation StartLoc, SourceLocation LParenLoc,
+ OMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *E, Stmt *HelperE,
+ OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation ModifierLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_device, StartLoc, EndLoc), OMPClauseWithPreInit(this),
- LParenLoc(LParenLoc), Device(E) {
+ : OMPClause(llvm::omp::OMPC_device, StartLoc, EndLoc),
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier),
+ ModifierLoc(ModifierLoc), Device(E) {
setPreInitStmt(HelperE, CaptureRegion);
}
/// Build an empty clause.
OMPDeviceClause()
- : OMPClause(OMPC_device, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_device, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
@@ -4134,6 +4623,12 @@ public:
/// Return device number.
Expr *getDevice() const { return cast<Expr>(Device); }
+ /// Gets modifier.
+ OpenMPDeviceClauseModifier getModifier() const { return Modifier; }
+
+ /// Gets modifier location.
+ SourceLocation getModifierLoc() const { return ModifierLoc; }
+
child_range children() { return child_range(&Device, &Device + 1); }
const_child_range children() const {
@@ -4148,7 +4643,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_device;
+ return T->getClauseKind() == llvm::omp::OMPC_device;
}
};
@@ -4165,11 +4660,12 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_threads, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPThreadsClause()
- : OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) {
+ }
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -4187,7 +4683,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_threads;
+ return T->getClauseKind() == llvm::omp::OMPC_threads;
}
};
@@ -4204,10 +4700,11 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_simd, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_simd, StartLoc, EndLoc) {}
/// Build an empty clause.
- OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {}
+ OMPSIMDClause()
+ : OMPClause(llvm::omp::OMPC_simd, SourceLocation(), SourceLocation()) {}
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -4225,7 +4722,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_simd;
+ return T->getClauseKind() == llvm::omp::OMPC_simd;
}
};
@@ -4853,19 +5350,14 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
return getUniqueDeclarationsNum() + getTotalComponentListNum();
}
-public:
- /// Number of allowed map-type-modifiers.
- static constexpr unsigned NumberOfModifiers =
- OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1;
-
private:
/// Map-type-modifiers for the 'map' clause.
- OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = {
+ OpenMPMapModifierKind MapTypeModifiers[NumberOfOMPMapClauseModifiers] = {
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
OMPC_MAP_MODIFIER_unknown};
/// Location of map-type-modifiers for the 'map' clause.
- SourceLocation MapTypeModifiersLoc[NumberOfModifiers];
+ SourceLocation MapTypeModifiersLoc[NumberOfOMPMapClauseModifiers];
/// Map type for the 'map' clause.
OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
@@ -4906,8 +5398,8 @@ private:
OpenMPMapClauseKind MapType, bool MapTypeIsImplicit,
SourceLocation MapLoc, const OMPVarListLocTy &Locs,
const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(OMPC_map, Locs, Sizes, &MapperQualifierLoc,
- &MapperIdInfo),
+ : OMPMappableExprListClause(llvm::omp::OMPC_map, Locs, Sizes,
+ &MapperQualifierLoc, &MapperIdInfo),
MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {
assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() &&
"Unexpected number of map type modifiers.");
@@ -4927,14 +5419,15 @@ private:
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(OMPC_map, OMPVarListLocTy(), Sizes) {}
+ : OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(),
+ Sizes) {}
/// Set map-type-modifier for the clause.
///
/// \param I index for map-type-modifier.
/// \param T map-type-modifier for the clause.
void setMapTypeModifier(unsigned I, OpenMPMapModifierKind T) {
- assert(I < NumberOfModifiers &&
+ assert(I < NumberOfOMPMapClauseModifiers &&
"Unexpected index to store map type modifier, exceeds array size.");
MapTypeModifiers[I] = T;
}
@@ -4944,7 +5437,7 @@ private:
/// \param I index for map-type-modifier location.
/// \param TLoc map-type-modifier location.
void setMapTypeModifierLoc(unsigned I, SourceLocation TLoc) {
- assert(I < NumberOfModifiers &&
+ assert(I < NumberOfOMPMapClauseModifiers &&
"Index to store map type modifier location exceeds array size.");
MapTypeModifiersLoc[I] = TLoc;
}
@@ -5019,7 +5512,7 @@ public:
///
/// \param Cnt index for map-type-modifier.
OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY {
- assert(Cnt < NumberOfModifiers &&
+ assert(Cnt < NumberOfOMPMapClauseModifiers &&
"Requested modifier exceeds the total number of modifiers.");
return MapTypeModifiers[Cnt];
}
@@ -5029,7 +5522,7 @@ public:
///
/// \param Cnt index for map-type-modifier location.
SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY {
- assert(Cnt < NumberOfModifiers &&
+ assert(Cnt < NumberOfOMPMapClauseModifiers &&
"Requested modifier location exceeds total number of modifiers.");
return MapTypeModifiersLoc[Cnt];
}
@@ -5074,7 +5567,7 @@ public:
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_map;
+ return T->getClauseKind() == llvm::omp::OMPC_map;
}
};
@@ -5113,14 +5606,15 @@ public:
OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this),
- LParenLoc(LParenLoc), NumTeams(E) {
+ : OMPClause(llvm::omp::OMPC_num_teams, StartLoc, EndLoc),
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTeams(E) {
setPreInitStmt(HelperE, CaptureRegion);
}
/// Build an empty clause.
OMPNumTeamsClause()
- : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_num_teams, SourceLocation(),
+ SourceLocation()),
OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
@@ -5149,7 +5643,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_num_teams;
+ return T->getClauseKind() == llvm::omp::OMPC_num_teams;
}
};
@@ -5189,14 +5683,15 @@ public:
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_thread_limit, StartLoc, EndLoc),
+ : OMPClause(llvm::omp::OMPC_thread_limit, StartLoc, EndLoc),
OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) {
setPreInitStmt(HelperE, CaptureRegion);
}
/// Build an empty clause.
OMPThreadLimitClause()
- : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_thread_limit, SourceLocation(),
+ SourceLocation()),
OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
@@ -5225,7 +5720,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_thread_limit;
+ return T->getClauseKind() == llvm::omp::OMPC_thread_limit;
}
};
@@ -5264,14 +5759,14 @@ public:
OMPPriorityClause(Expr *Priority, Stmt *HelperPriority,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_priority, StartLoc, EndLoc), OMPClauseWithPreInit(this),
- LParenLoc(LParenLoc), Priority(Priority) {
+ : OMPClause(llvm::omp::OMPC_priority, StartLoc, EndLoc),
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Priority(Priority) {
setPreInitStmt(HelperPriority, CaptureRegion);
}
/// Build an empty clause.
OMPPriorityClause()
- : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_priority, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
@@ -5299,7 +5794,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_priority;
+ return T->getClauseKind() == llvm::omp::OMPC_priority;
}
};
@@ -5335,14 +5830,15 @@ public:
OMPGrainsizeClause(Expr *Size, Stmt *HelperSize,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_grainsize, StartLoc, EndLoc), OMPClauseWithPreInit(this),
- LParenLoc(LParenLoc), Grainsize(Size) {
+ : OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc),
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) {
setPreInitStmt(HelperSize, CaptureRegion);
}
/// Build an empty clause.
explicit OMPGrainsizeClause()
- : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_grainsize, SourceLocation(),
+ SourceLocation()),
OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
@@ -5367,7 +5863,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_grainsize;
+ return T->getClauseKind() == llvm::omp::OMPC_grainsize;
}
};
@@ -5384,11 +5880,12 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_nogroup, StartLoc, EndLoc) {}
+ : OMPClause(llvm::omp::OMPC_nogroup, StartLoc, EndLoc) {}
/// Build an empty clause.
OMPNogroupClause()
- : OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_nogroup, SourceLocation(), SourceLocation()) {
+ }
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -5406,7 +5903,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_nogroup;
+ return T->getClauseKind() == llvm::omp::OMPC_nogroup;
}
};
@@ -5442,14 +5939,15 @@ public:
OMPNumTasksClause(Expr *Size, Stmt *HelperSize,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), OMPClauseWithPreInit(this),
- LParenLoc(LParenLoc), NumTasks(Size) {
+ : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc),
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) {
setPreInitStmt(HelperSize, CaptureRegion);
}
/// Build an empty clause.
explicit OMPNumTasksClause()
- : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_num_tasks, SourceLocation(),
+ SourceLocation()),
OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
@@ -5474,7 +5972,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_num_tasks;
+ return T->getClauseKind() == llvm::omp::OMPC_num_tasks;
}
};
@@ -5506,11 +6004,12 @@ public:
/// \param EndLoc Ending location of the clause.
OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ : OMPClause(llvm::omp::OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc),
Hint(Hint) {}
/// Build an empty clause.
- OMPHintClause() : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()) {}
+ OMPHintClause()
+ : OMPClause(llvm::omp::OMPC_hint, SourceLocation(), SourceLocation()) {}
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -5535,7 +6034,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_hint;
+ return T->getClauseKind() == llvm::omp::OMPC_hint;
}
};
@@ -5607,7 +6106,7 @@ public:
SourceLocation EndLoc,
OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize,
Stmt *HelperChunkSize)
- : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc),
+ : OMPClause(llvm::omp::OMPC_dist_schedule, StartLoc, EndLoc),
OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind),
KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) {
setPreInitStmt(HelperChunkSize);
@@ -5615,7 +6114,8 @@ public:
/// Build an empty clause.
explicit OMPDistScheduleClause()
- : OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()),
+ : OMPClause(llvm::omp::OMPC_dist_schedule, SourceLocation(),
+ SourceLocation()),
OMPClauseWithPreInit(this) {}
/// Get kind of the clause.
@@ -5654,7 +6154,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_dist_schedule;
+ return T->getClauseKind() == llvm::omp::OMPC_dist_schedule;
}
};
@@ -5724,12 +6224,14 @@ public:
SourceLocation MLoc, SourceLocation KLoc,
SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind,
OpenMPDefaultmapClauseModifier M)
- : OMPClause(OMPC_defaultmap, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Modifier(M), ModifierLoc(MLoc), Kind(Kind), KindLoc(KLoc) {}
+ : OMPClause(llvm::omp::OMPC_defaultmap, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Modifier(M), ModifierLoc(MLoc), Kind(Kind),
+ KindLoc(KLoc) {}
/// Build an empty clause.
explicit OMPDefaultmapClause()
- : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()) {}
+ : OMPClause(llvm::omp::OMPC_defaultmap, SourceLocation(),
+ SourceLocation()) {}
/// Get kind of the clause.
OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; }
@@ -5766,7 +6268,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_defaultmap;
+ return T->getClauseKind() == llvm::omp::OMPC_defaultmap;
}
};
@@ -5804,8 +6306,8 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
DeclarationNameInfo MapperIdInfo,
const OMPVarListLocTy &Locs,
const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc,
- &MapperIdInfo) {}
+ : OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes,
+ &MapperQualifierLoc, &MapperIdInfo) {}
/// Build an empty clause.
///
@@ -5815,7 +6317,8 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(OMPC_to, OMPVarListLocTy(), Sizes) {}
+ : OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(),
+ Sizes) {}
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
@@ -5883,7 +6386,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_to;
+ return T->getClauseKind() == llvm::omp::OMPC_to;
}
};
@@ -5922,8 +6425,8 @@ class OMPFromClause final
DeclarationNameInfo MapperIdInfo,
const OMPVarListLocTy &Locs,
const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(OMPC_from, Locs, Sizes, &MapperQualifierLoc,
- &MapperIdInfo) {}
+ : OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes,
+ &MapperQualifierLoc, &MapperIdInfo) {}
/// Build an empty clause.
///
@@ -5933,7 +6436,8 @@ class OMPFromClause final
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(OMPC_from, OMPVarListLocTy(), Sizes) {}
+ : OMPMappableExprListClause(llvm::omp::OMPC_from, OMPVarListLocTy(),
+ Sizes) {}
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
@@ -6001,7 +6505,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_from;
+ return T->getClauseKind() == llvm::omp::OMPC_from;
}
};
@@ -6035,7 +6539,8 @@ class OMPUseDevicePtrClause final
/// NumComponents: total number of expression components in the clause.
explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs,
const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(OMPC_use_device_ptr, Locs, Sizes) {}
+ : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) {
+ }
/// Build an empty clause.
///
@@ -6045,8 +6550,8 @@ class OMPUseDevicePtrClause final
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(OMPC_use_device_ptr, OMPVarListLocTy(),
- Sizes) {}
+ : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr,
+ OMPVarListLocTy(), Sizes) {}
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
@@ -6164,7 +6669,111 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_use_device_ptr;
+ return T->getClauseKind() == llvm::omp::OMPC_use_device_ptr;
+ }
+};
+
+/// This represents clause 'use_device_addr' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp target data use_device_addr(a,b)
+/// \endcode
+/// In this example directive '#pragma omp target data' has clause
+/// 'use_device_addr' with the variables 'a' and 'b'.
+class OMPUseDeviceAddrClause final
+ : public OMPMappableExprListClause<OMPUseDeviceAddrClause>,
+ private llvm::TrailingObjects<
+ OMPUseDeviceAddrClause, Expr *, ValueDecl *, unsigned,
+ OMPClauseMappableExprCommon::MappableComponent> {
+ friend class OMPClauseReader;
+ friend OMPMappableExprListClause;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Build clause with number of variables \a NumVars.
+ ///
+ /// \param Locs Locations needed to build a mappable clause. It includes 1)
+ /// StartLoc: starting location of the clause (the clause keyword); 2)
+ /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
+ /// \param Sizes All required sizes to build a mappable clause. It includes 1)
+ /// NumVars: number of expressions listed in this clause; 2)
+ /// NumUniqueDeclarations: number of unique base declarations in this clause;
+ /// 3) NumComponentLists: number of component lists in this clause; and 4)
+ /// NumComponents: total number of expression components in the clause.
+ explicit OMPUseDeviceAddrClause(const OMPVarListLocTy &Locs,
+ const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(llvm::omp::OMPC_use_device_addr, Locs,
+ Sizes) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param Sizes All required sizes to build a mappable clause. It includes 1)
+ /// NumVars: number of expressions listed in this clause; 2)
+ /// NumUniqueDeclarations: number of unique base declarations in this clause;
+ /// 3) NumComponentLists: number of component lists in this clause; and 4)
+ /// NumComponents: total number of expression components in the clause.
+ explicit OMPUseDeviceAddrClause(const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(llvm::omp::OMPC_use_device_addr,
+ OMPVarListLocTy(), Sizes) {}
+
+ /// Define the sizes of each trailing object array except the last one. This
+ /// is required for TrailingObjects to work properly.
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return varlist_size();
+ }
+ size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
+ return getUniqueDeclarationsNum();
+ }
+ size_t numTrailingObjects(OverloadToken<unsigned>) const {
+ return getUniqueDeclarationsNum() + getTotalComponentListNum();
+ }
+
+public:
+ /// Creates clause with a list of variables \a Vars.
+ ///
+ /// \param C AST context.
+ /// \param Locs Locations needed to build a mappable clause. It includes 1)
+ /// StartLoc: starting location of the clause (the clause keyword); 2)
+ /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
+ /// \param Vars The original expression used in the clause.
+ /// \param Declarations Declarations used in the clause.
+ /// \param ComponentLists Component lists used in the clause.
+ static OMPUseDeviceAddrClause *
+ Create(const ASTContext &C, const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
+ MappableExprComponentListsRef ComponentLists);
+
+ /// Creates an empty clause with the place for \a NumVars variables.
+ ///
+ /// \param C AST context.
+ /// \param Sizes All required sizes to build a mappable clause. It includes 1)
+ /// NumVars: number of expressions listed in this clause; 2)
+ /// NumUniqueDeclarations: number of unique base declarations in this clause;
+ /// 3) NumComponentLists: number of component lists in this clause; and 4)
+ /// NumComponents: total number of expression components in the clause.
+ static OMPUseDeviceAddrClause *
+ CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes);
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<OMPUseDeviceAddrClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_use_device_addr;
}
};
@@ -6198,7 +6807,7 @@ class OMPIsDevicePtrClause final
/// NumComponents: total number of expression components in the clause.
explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs,
const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(OMPC_is_device_ptr, Locs, Sizes) {}
+ : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, Locs, Sizes) {}
/// Build an empty clause.
///
@@ -6208,8 +6817,8 @@ class OMPIsDevicePtrClause final
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(OMPC_is_device_ptr, OMPVarListLocTy(),
- Sizes) {}
+ : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr,
+ OMPVarListLocTy(), Sizes) {}
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
@@ -6267,7 +6876,7 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_is_device_ptr;
+ return T->getClauseKind() == llvm::omp::OMPC_is_device_ptr;
}
};
@@ -6293,15 +6902,16 @@ class OMPNontemporalClause final
/// \param N Number of the variables in the clause.
OMPNontemporalClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPNontemporalClause>(OMPC_nontemporal, StartLoc,
- LParenLoc, EndLoc, N) {}
+ : OMPVarListClause<OMPNontemporalClause>(llvm::omp::OMPC_nontemporal,
+ StartLoc, LParenLoc, EndLoc, N) {
+ }
/// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPNontemporalClause(unsigned N)
: OMPVarListClause<OMPNontemporalClause>(
- OMPC_nontemporal, SourceLocation(), SourceLocation(),
+ llvm::omp::OMPC_nontemporal, SourceLocation(), SourceLocation(),
SourceLocation(), N) {}
/// Get the list of privatied copies if the member expression was captured by
@@ -6363,7 +6973,563 @@ public:
}
static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_nontemporal;
+ return T->getClauseKind() == llvm::omp::OMPC_nontemporal;
+ }
+};
+
+/// This represents 'order' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp simd order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'order'
+/// clause with kind 'concurrent'.
+class OMPOrderClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// A kind of the 'default' clause.
+ OpenMPOrderClauseKind Kind = OMPC_ORDER_unknown;
+
+ /// Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// Set kind of the clause.
+ ///
+ /// \param K Argument of clause.
+ void setKind(OpenMPOrderClauseKind K) { Kind = K; }
+
+ /// Set argument location.
+ ///
+ /// \param KLoc Argument location.
+ void setKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+public:
+ /// Build 'order' clause with argument \p A ('concurrent').
+ ///
+ /// \param A Argument of the clause ('concurrent').
+ /// \param ALoc Starting location of the argument.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
+
+ /// Build an empty clause.
+ OMPOrderClause()
+ : OMPClause(llvm::omp::OMPC_order, SourceLocation(), SourceLocation()) {}
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns kind of the clause.
+ OpenMPOrderClauseKind getKind() const { return Kind; }
+
+ /// Returns location of clause kind.
+ SourceLocation getKindKwLoc() const { return KindKwLoc; }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_order;
+ }
+};
+
+/// This represents 'destroy' clause in the '#pragma omp depobj'
+/// directive.
+///
+/// \code
+/// #pragma omp depobj(a) destroy
+/// \endcode
+/// In this example directive '#pragma omp depobj' has 'destroy' clause.
+class OMPDestroyClause final : public OMPClause {
+public:
+ /// Build 'destroy' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPDestroyClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPDestroyClause()
+ : OMPClause(llvm::omp::OMPC_destroy, SourceLocation(), SourceLocation()) {
+ }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_destroy;
+ }
+};
+
+/// This represents 'detach' clause in the '#pragma omp task' directive.
+///
+/// \code
+/// #pragma omp task detach(evt)
+/// \endcode
+/// In this example directive '#pragma omp detach' has simple 'detach' clause
+/// with the variable 'evt'.
+class OMPDetachClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// Expression of the 'detach' clause.
+ Stmt *Evt = nullptr;
+
+ /// Set condition.
+ void setEventHandler(Expr *E) { Evt = E; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+ /// Build 'detach' clause with event-handler \a Evt.
+ ///
+ /// \param Evt Event handler expression.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Evt(Evt) {}
+
+ /// Build an empty clause.
+ OMPDetachClause()
+ : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {}
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns event-handler expression.
+ Expr *getEventHandler() const { return cast_or_null<Expr>(Evt); }
+
+ child_range children() { return child_range(&Evt, &Evt + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&Evt, &Evt + 1);
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_detach;
+ }
+};
+
+/// This represents clause 'inclusive' in the '#pragma omp scan' directive.
+///
+/// \code
+/// #pragma omp scan inclusive(a,b)
+/// \endcode
+/// In this example directive '#pragma omp scan' has clause 'inclusive'
+/// with the variables 'a' and 'b'.
+class OMPInclusiveClause final
+ : public OMPVarListClause<OMPInclusiveClause>,
+ private llvm::TrailingObjects<OMPInclusiveClause, Expr *> {
+ friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ OMPInclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPInclusiveClause>(llvm::omp::OMPC_inclusive,
+ StartLoc, LParenLoc, EndLoc, N) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ explicit OMPInclusiveClause(unsigned N)
+ : OMPVarListClause<OMPInclusiveClause>(llvm::omp::OMPC_inclusive,
+ SourceLocation(), SourceLocation(),
+ SourceLocation(), N) {}
+
+public:
+ /// Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the original variables.
+ static OMPInclusiveClause *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+
+ /// Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ static OMPInclusiveClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<OMPInclusiveClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_inclusive;
+ }
+};
+
+/// This represents clause 'exclusive' in the '#pragma omp scan' directive.
+///
+/// \code
+/// #pragma omp scan exclusive(a,b)
+/// \endcode
+/// In this example directive '#pragma omp scan' has clause 'exclusive'
+/// with the variables 'a' and 'b'.
+class OMPExclusiveClause final
+ : public OMPVarListClause<OMPExclusiveClause>,
+ private llvm::TrailingObjects<OMPExclusiveClause, Expr *> {
+ friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ OMPExclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPExclusiveClause>(llvm::omp::OMPC_exclusive,
+ StartLoc, LParenLoc, EndLoc, N) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ explicit OMPExclusiveClause(unsigned N)
+ : OMPVarListClause<OMPExclusiveClause>(llvm::omp::OMPC_exclusive,
+ SourceLocation(), SourceLocation(),
+ SourceLocation(), N) {}
+
+public:
+ /// Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the original variables.
+ static OMPExclusiveClause *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+
+ /// Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ static OMPExclusiveClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<OMPExclusiveClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_exclusive;
+ }
+};
+
+/// This represents clause 'uses_allocators' in the '#pragma omp target'-based
+/// directives.
+///
+/// \code
+/// #pragma omp target uses_allocators(default_allocator, my_allocator(traits))
+/// \endcode
+/// In this example directive '#pragma omp target' has clause 'uses_allocators'
+/// with the allocators 'default_allocator' and user-defined 'my_allocator'.
+class OMPUsesAllocatorsClause final
+ : public OMPClause,
+ private llvm::TrailingObjects<OMPUsesAllocatorsClause, Expr *,
+ SourceLocation> {
+public:
+ /// Data for list of allocators.
+ struct Data {
+ /// Allocator.
+ Expr *Allocator = nullptr;
+ /// Allocator traits.
+ Expr *AllocatorTraits = nullptr;
+ /// Locations of '(' and ')' symbols.
+ SourceLocation LParenLoc, RParenLoc;
+ };
+
+private:
+ friend class OMPClauseReader;
+ friend TrailingObjects;
+
+ enum class ExprOffsets {
+ Allocator,
+ AllocatorTraits,
+ Total,
+ };
+
+ enum class ParenLocsOffsets {
+ LParen,
+ RParen,
+ Total,
+ };
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+ /// Total number of allocators in the clause.
+ unsigned NumOfAllocators = 0;
+
+ /// Build clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of allocators asssociated with the clause.
+ OMPUsesAllocatorsClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPClause(llvm::omp::OMPC_uses_allocators, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), NumOfAllocators(N) {}
+
+ /// Build an empty clause.
+ /// \param N Number of allocators asssociated with the clause.
+ ///
+ explicit OMPUsesAllocatorsClause(unsigned N)
+ : OMPClause(llvm::omp::OMPC_uses_allocators, SourceLocation(),
+ SourceLocation()),
+ NumOfAllocators(N) {}
+
+ unsigned numTrailingObjects(OverloadToken<Expr *>) const {
+ return NumOfAllocators * static_cast<int>(ExprOffsets::Total);
+ }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Sets the allocators data for the clause.
+ void setAllocatorsData(ArrayRef<OMPUsesAllocatorsClause::Data> Data);
+
+public:
+ /// Creates clause with a list of allocators \p Data.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param Data List of allocators.
+ static OMPUsesAllocatorsClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<OMPUsesAllocatorsClause::Data> Data);
+
+ /// Creates an empty clause with the place for \p N allocators.
+ ///
+ /// \param C AST context.
+ /// \param N The number of allocators.
+ static OMPUsesAllocatorsClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns number of allocators associated with the clause.
+ unsigned getNumberOfAllocators() const { return NumOfAllocators; }
+
+ /// Returns data for the specified allocator.
+ OMPUsesAllocatorsClause::Data getAllocatorData(unsigned I) const;
+
+ // Iterators
+ child_range children() {
+ Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
+ return child_range(Begin, Begin + NumOfAllocators *
+ static_cast<int>(ExprOffsets::Total));
+ }
+ const_child_range children() const {
+ Stmt *const *Begin =
+ reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
+ return const_child_range(
+ Begin, Begin + NumOfAllocators * static_cast<int>(ExprOffsets::Total));
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_uses_allocators;
+ }
+};
+
+/// This represents clause 'affinity' in the '#pragma omp task'-based
+/// directives.
+///
+/// \code
+/// #pragma omp task affinity(iterator(i = 0:n) : ([3][n])a, b[:n], c[i])
+/// \endcode
+/// In this example directive '#pragma omp task' has clause 'affinity' with the
+/// affinity modifer 'iterator(i = 0:n)' and locator items '([3][n])a', 'b[:n]'
+/// and 'c[i]'.
+class OMPAffinityClause final
+ : public OMPVarListClause<OMPAffinityClause>,
+ private llvm::TrailingObjects<OMPAffinityClause, Expr *> {
+ friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Location of ':' symbol.
+ SourceLocation ColonLoc;
+
+ /// Build clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of locators asssociated with the clause.
+ OMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity, StartLoc,
+ LParenLoc, EndLoc, N) {}
+
+ /// Build an empty clause.
+ /// \param N Number of locators asssociated with the clause.
+ ///
+ explicit OMPAffinityClause(unsigned N)
+ : OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity,
+ SourceLocation(), SourceLocation(),
+ SourceLocation(), N) {}
+
+ /// Sets the affinity modifier for the clause, if any.
+ void setModifier(Expr *E) {
+ getTrailingObjects<Expr *>()[varlist_size()] = E;
+ }
+
+ /// Sets the location of ':' symbol.
+ void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+
+public:
+ /// Creates clause with a modifier a list of locator items.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param Locators List of locator items.
+ static OMPAffinityClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc, Expr *Modifier,
+ ArrayRef<Expr *> Locators);
+
+ /// Creates an empty clause with the place for \p N locator items.
+ ///
+ /// \param C AST context.
+ /// \param N The number of locator items.
+ static OMPAffinityClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ /// Gets affinity modifier.
+ Expr *getModifier() { return getTrailingObjects<Expr *>()[varlist_size()]; }
+ Expr *getModifier() const {
+ return getTrailingObjects<Expr *>()[varlist_size()];
+ }
+
+ /// Gets the location of ':' symbol.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+
+ // Iterators
+ child_range children() {
+ int Offset = getModifier() ? 1 : 0;
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end() + Offset));
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<OMPAffinityClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_affinity;
}
};
@@ -6372,21 +7538,26 @@ public:
template<class ImplClass, template <typename> class Ptr, typename RetTy>
class OMPClauseVisitorBase {
public:
-#define PTR(CLASS) typename Ptr<CLASS>::type
+#define PTR(CLASS) Ptr<CLASS>
#define DISPATCH(CLASS) \
return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))
-#define OPENMP_CLAUSE(Name, Class) \
+#define OMP_CLAUSE_CLASS(Enum, Str, Class) \
RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); }
-#include "clang/Basic/OpenMPKinds.def"
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
RetTy Visit(PTR(OMPClause) S) {
// Top switch clause: visit each OMPClause.
switch (S->getClauseKind()) {
- default: llvm_unreachable("Unknown clause kind!");
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S));
-#include "clang/Basic/OpenMPKinds.def"
+#define OMP_CLAUSE_CLASS(Enum, Str, Class) \
+ case llvm::omp::Clause::Enum: \
+ return Visit##Class(static_cast<PTR(Class)>(S));
+#define OMP_CLAUSE_NO_CLASS(Enum, Str) \
+ case llvm::omp::Clause::Enum: \
+ break;
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+ default:
+ break;
}
}
// Base case, ignore it. :)
@@ -6395,12 +7566,11 @@ public:
#undef DISPATCH
};
-template <typename T>
-using const_ptr = typename std::add_pointer<typename std::add_const<T>::type>;
+template <typename T> using const_ptr = std::add_pointer_t<std::add_const_t<T>>;
-template<class ImplClass, typename RetTy = void>
-class OMPClauseVisitor :
- public OMPClauseVisitorBase <ImplClass, std::add_pointer, RetTy> {};
+template <class ImplClass, typename RetTy = void>
+class OMPClauseVisitor
+ : public OMPClauseVisitorBase<ImplClass, std::add_pointer_t, RetTy> {};
template<class ImplClass, typename RetTy = void>
class ConstOMPClauseVisitor :
public OMPClauseVisitorBase <ImplClass, const_ptr, RetTy> {};
@@ -6416,9 +7586,69 @@ public:
OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
: OS(OS), Policy(Policy) {}
-#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S);
-#include "clang/Basic/OpenMPKinds.def"
+#define OMP_CLAUSE_CLASS(Enum, Str, Class) \
+ void Visit##Class(Class *S);
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+};
+
+struct OMPTraitProperty {
+ llvm::omp::TraitProperty Kind = llvm::omp::TraitProperty::invalid;
+};
+struct OMPTraitSelector {
+ Expr *ScoreOrCondition = nullptr;
+ llvm::omp::TraitSelector Kind = llvm::omp::TraitSelector::invalid;
+ llvm::SmallVector<OMPTraitProperty, 1> Properties;
+};
+struct OMPTraitSet {
+ llvm::omp::TraitSet Kind = llvm::omp::TraitSet::invalid;
+ llvm::SmallVector<OMPTraitSelector, 2> Selectors;
+};
+
+/// Helper data structure representing the traits in a match clause of an
+/// `declare variant` or `metadirective`. The outer level is an ordered
+/// collection of selector sets, each with an associated kind and an ordered
+/// collection of selectors. A selector has a kind, an optional score/condition,
+/// and an ordered collection of properties.
+class OMPTraitInfo {
+ /// Private constructor accesible only by ASTContext.
+ OMPTraitInfo() {}
+ friend class ASTContext;
+
+public:
+ /// Reconstruct a (partial) OMPTraitInfo object from a mangled name.
+ OMPTraitInfo(StringRef MangledName);
+
+ /// The outermost level of selector sets.
+ llvm::SmallVector<OMPTraitSet, 2> Sets;
+
+ bool anyScoreOrCondition(
+ llvm::function_ref<bool(Expr *&, bool /* IsScore */)> Cond) {
+ return llvm::any_of(Sets, [&](OMPTraitSet &Set) {
+ return llvm::any_of(
+ Set.Selectors, [&](OMPTraitSelector &Selector) {
+ return Cond(Selector.ScoreOrCondition,
+ /* IsScore */ Selector.Kind !=
+ llvm::omp::TraitSelector::user_condition);
+ });
+ });
+ }
+
+ /// Create a variant match info object from this trait info object. While the
+ /// former is a flat representation the actual main difference is that the
+ /// latter uses clang::Expr to store the score/condition while the former is
+ /// independent of clang. Thus, expressions and conditions are evaluated in
+ /// this method.
+ void getAsVariantMatchInfo(ASTContext &ASTCtx,
+ llvm::omp::VariantMatchInfo &VMI) const;
+
+ /// Return a string representation identifying this context selector.
+ std::string getMangledName() const;
+
+ /// Print a human readable representation into \p OS.
+ void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
};
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI);
} // namespace clang
diff --git a/clang/include/clang/AST/ParentMapContext.h b/clang/include/clang/AST/ParentMapContext.h
new file mode 100644
index 000000000000..be4d75df7b99
--- /dev/null
+++ b/clang/include/clang/AST/ParentMapContext.h
@@ -0,0 +1,144 @@
+//===- ParentMapContext.h - Map of parents using DynTypedNode -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Similar to ParentMap.h, but generalizes to non-Stmt nodes, which can have
+// multiple parents.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_PARENTMAPCONTEXT_H
+#define LLVM_CLANG_AST_PARENTMAPCONTEXT_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
+
+namespace clang {
+class DynTypedNodeList;
+
+class ParentMapContext {
+public:
+ ParentMapContext(ASTContext &Ctx);
+
+ ~ParentMapContext();
+
+ /// Returns the parents of the given node (within the traversal scope).
+ ///
+ /// Note that this will lazily compute the parents of all nodes
+ /// and store them for later retrieval. Thus, the first call is O(n)
+ /// in the number of AST nodes.
+ ///
+ /// Caveats and FIXMEs:
+ /// Calculating the parent map over all AST nodes will need to load the
+ /// full AST. This can be undesirable in the case where the full AST is
+ /// expensive to create (for example, when using precompiled header
+ /// preambles). Thus, there are good opportunities for optimization here.
+ /// One idea is to walk the given node downwards, looking for references
+ /// to declaration contexts - once a declaration context is found, compute
+ /// the parent map for the declaration context; if that can satisfy the
+ /// request, loading the whole AST can be avoided. Note that this is made
+ /// more complex by statements in templates having multiple parents - those
+ /// problems can be solved by building closure over the templated parts of
+ /// the AST, which also avoids touching large parts of the AST.
+ /// Additionally, we will want to add an interface to already give a hint
+ /// where to search for the parents, for example when looking at a statement
+ /// inside a certain function.
+ ///
+ /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
+ /// NestedNameSpecifier or NestedNameSpecifierLoc.
+ template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node);
+
+ DynTypedNodeList getParents(const DynTypedNode &Node);
+
+ /// Clear parent maps.
+ void clear();
+
+ TraversalKind getTraversalKind() const { return Traversal; }
+ void setTraversalKind(TraversalKind TK) { Traversal = TK; }
+
+ const Expr *traverseIgnored(const Expr *E) const;
+ Expr *traverseIgnored(Expr *E) const;
+ DynTypedNode traverseIgnored(const DynTypedNode &N) const;
+
+private:
+ ASTContext &ASTCtx;
+ class ParentMap;
+ TraversalKind Traversal = TK_AsIs;
+ std::unique_ptr<ParentMap> Parents;
+};
+
+class TraversalKindScope {
+ ParentMapContext &Ctx;
+ TraversalKind TK = TK_AsIs;
+
+public:
+ TraversalKindScope(ASTContext &ASTCtx, llvm::Optional<TraversalKind> ScopeTK)
+ : Ctx(ASTCtx.getParentMapContext()) {
+ TK = Ctx.getTraversalKind();
+ if (ScopeTK)
+ Ctx.setTraversalKind(*ScopeTK);
+ }
+
+ ~TraversalKindScope() { Ctx.setTraversalKind(TK); }
+};
+
+/// Container for either a single DynTypedNode or for an ArrayRef to
+/// DynTypedNode. For use with ParentMap.
+class DynTypedNodeList {
+ llvm::AlignedCharArrayUnion<DynTypedNode, ArrayRef<DynTypedNode>> Storage;
+ bool IsSingleNode;
+
+public:
+ DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
+ new (Storage.buffer) DynTypedNode(N);
+ }
+
+ DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
+ new (Storage.buffer) ArrayRef<DynTypedNode>(A);
+ }
+
+ const DynTypedNode *begin() const {
+ if (!IsSingleNode)
+ return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
+ ->begin();
+ return reinterpret_cast<const DynTypedNode *>(Storage.buffer);
+ }
+
+ const DynTypedNode *end() const {
+ if (!IsSingleNode)
+ return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
+ ->end();
+ return reinterpret_cast<const DynTypedNode *>(Storage.buffer) + 1;
+ }
+
+ size_t size() const { return end() - begin(); }
+ bool empty() const { return begin() == end(); }
+
+ const DynTypedNode &operator[](size_t N) const {
+ assert(N < size() && "Out of bounds!");
+ return *(begin() + N);
+ }
+};
+
+template <typename NodeT>
+inline DynTypedNodeList ParentMapContext::getParents(const NodeT &Node) {
+ return getParents(DynTypedNode::create(Node));
+}
+
+template <typename NodeT>
+inline DynTypedNodeList ASTContext::getParents(const NodeT &Node) {
+ return getParentMapContext().getParents(Node);
+}
+
+template <>
+inline DynTypedNodeList ASTContext::getParents(const DynTypedNode &Node) {
+ return getParentMapContext().getParents(Node);
+}
+
+} // namespace clang
+
+#endif
diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h
index 80eec6a5a8be..616647f44430 100644
--- a/clang/include/clang/AST/PrettyPrinter.h
+++ b/clang/include/clang/AST/PrettyPrinter.h
@@ -36,7 +36,9 @@ protected:
public:
/// Remap a path to a form suitable for printing.
- virtual std::string remapPath(StringRef Path) const { return Path; }
+ virtual std::string remapPath(StringRef Path) const {
+ return std::string(Path);
+ }
};
/// Describes how types, statements, expressions, and declarations should be
@@ -55,12 +57,13 @@ struct PrintingPolicy {
SuppressLifetimeQualifiers(false),
SuppressTemplateArgsInCXXConstructors(false), Bool(LO.Bool),
Restrict(LO.C99), Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11),
- UseVoidForZeroParams(!LO.CPlusPlus), TerseOutput(false),
+ UseVoidForZeroParams(!LO.CPlusPlus),
+ SplitTemplateClosers(!LO.CPlusPlus11), TerseOutput(false),
PolishForDeclaration(false), Half(LO.Half),
MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
MSVCFormatting(false), ConstantsAsWritten(false),
SuppressImplicitBase(false), FullyQualifiedName(false),
- PrintCanonicalTypes(false) {}
+ PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true) {}
/// Adjust this printing policy for cases where it's known that we're
/// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -181,6 +184,10 @@ struct PrintingPolicy {
/// with zero parameters.
unsigned UseVoidForZeroParams : 1;
+ /// Whether nested templates must be closed like 'a\<b\<c\> \>' rather than
+ /// 'a\<b\<c\>\>'.
+ unsigned SplitTemplateClosers : 1;
+
/// Provide a 'terse' output.
///
/// For example, in this mode we don't print function bodies, class members,
@@ -237,6 +244,11 @@ struct PrintingPolicy {
/// Whether to print types as written or canonically.
unsigned PrintCanonicalTypes : 1;
+ /// Whether to print an InjectedClassNameType with template arguments or as
+ /// written. When a template argument is unnamed, printing it results in
+ /// invalid C++ code.
+ unsigned PrintInjectedClassNameWithArguments : 1;
+
/// Callbacks to use to allow the behavior of printing to be customized.
const PrintingCallbacks *Callbacks = nullptr;
};
diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td
index 9aacdb9fee36..ba0f237a3bc3 100644
--- a/clang/include/clang/AST/PropertiesBase.td
+++ b/clang/include/clang/AST/PropertiesBase.td
@@ -99,6 +99,8 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
SubclassPropertyType<"TagDecl", DeclRef>;
def TemplateDeclRef :
SubclassPropertyType<"TemplateDecl", DeclRef>;
+ def ConceptDeclRef :
+ SubclassPropertyType<"ConceptDecl", DeclRef>;
def TemplateTypeParmDeclRef :
SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
def TemplateTemplateParmDeclRef :
diff --git a/clang/include/clang/AST/RawCommentList.h b/clang/include/clang/AST/RawCommentList.h
index 1eea56dee622..a18432c2b768 100644
--- a/clang/include/clang/AST/RawCommentList.h
+++ b/clang/include/clang/AST/RawCommentList.h
@@ -11,9 +11,9 @@
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
#include <map>
namespace clang {
@@ -21,7 +21,9 @@ namespace clang {
class ASTContext;
class ASTReader;
class Decl;
+class DiagnosticsEngine;
class Preprocessor;
+class SourceManager;
namespace comments {
class FullComment;
@@ -173,23 +175,6 @@ private:
friend class ASTReader;
};
-/// Compare comments' source locations.
-template<>
-class BeforeThanCompare<RawComment> {
- const SourceManager &SM;
-
-public:
- explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { }
-
- bool operator()(const RawComment &LHS, const RawComment &RHS) {
- return SM.isBeforeInTranslationUnit(LHS.getBeginLoc(), RHS.getBeginLoc());
- }
-
- bool operator()(const RawComment *LHS, const RawComment *RHS) {
- return operator()(*LHS, *RHS);
- }
-};
-
/// This class represents all comments included in the translation unit,
/// sorted in order of appearance in the translation unit.
class RawCommentList {
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index f8ab8e451d8c..3dcfc9fee629 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -23,6 +23,7 @@
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
@@ -47,29 +48,6 @@
#include <cstddef>
#include <type_traits>
-// The following three macros are used for meta programming. The code
-// using them is responsible for defining macro OPERATOR().
-
-// All unary operators.
-#define UNARYOP_LIST() \
- OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \
- OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \
- OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \
- OPERATOR(Extension) OPERATOR(Coawait)
-
-// All binary operators (excluding compound assign operators).
-#define BINOP_LIST() \
- OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \
- OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \
- OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
- OPERATOR(NE) OPERATOR(Cmp) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \
- OPERATOR(LAnd) OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
-
-// All compound assign operators.
-#define CAO_LIST() \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
- OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
-
namespace clang {
// A helper macro to implement short-circuiting when recursing. It
@@ -82,6 +60,42 @@ namespace clang {
return false; \
} while (false)
+namespace detail {
+
+template <typename T, typename U>
+struct has_same_member_pointer_type : std::false_type {};
+template <typename T, typename U, typename R, typename... P>
+struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
+ : std::true_type {};
+
+template <bool has_same_type> struct is_same_method_impl {
+ template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
+ static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
+ SecondMethodPtrTy SecondMethodPtr) {
+ return false;
+ }
+};
+
+template <> struct is_same_method_impl<true> {
+ template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
+ static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
+ SecondMethodPtrTy SecondMethodPtr) {
+ return FirstMethodPtr == SecondMethodPtr;
+ }
+};
+
+/// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr
+/// are pointers to the same non-static member function.
+template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
+bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
+ SecondMethodPtrTy SecondMethodPtr) {
+ return is_same_method_impl<has_same_member_pointer_type<
+ FirstMethodPtrTy,
+ SecondMethodPtrTy>::value>::isSameMethod(FirstMethodPtr, SecondMethodPtr);
+}
+
+} // end namespace detail
+
/// A class that does preorder or postorder
/// depth-first traversal on the entire Clang AST and visits each node.
///
@@ -324,26 +338,20 @@ public:
Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
private:
- template<typename T, typename U>
- struct has_same_member_pointer_type : std::false_type {};
- template<typename T, typename U, typename R, typename... P>
- struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
- : std::true_type {};
-
// Traverse the given statement. If the most-derived traverse function takes a
// data recursion queue, pass it on; otherwise, discard it. Note that the
// first branch of this conditional must compile whether or not the derived
// class can take a queue, so if we're taking the second arm, make the first
// arm call our function rather than the derived class version.
#define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \
- (has_same_member_pointer_type<decltype( \
- &RecursiveASTVisitor::Traverse##NAME), \
- decltype(&Derived::Traverse##NAME)>::value \
- ? static_cast<typename std::conditional< \
- has_same_member_pointer_type< \
+ (::clang::detail::has_same_member_pointer_type< \
+ decltype(&RecursiveASTVisitor::Traverse##NAME), \
+ decltype(&Derived::Traverse##NAME)>::value \
+ ? static_cast<std::conditional_t< \
+ ::clang::detail::has_same_member_pointer_type< \
decltype(&RecursiveASTVisitor::Traverse##NAME), \
decltype(&Derived::Traverse##NAME)>::value, \
- Derived &, RecursiveASTVisitor &>::type>(*this) \
+ Derived &, RecursiveASTVisitor &>>(*this) \
.Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \
: getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)))
@@ -376,60 +384,6 @@ public:
bool Visit##CLASS(CLASS *S) { return true; }
#include "clang/AST/StmtNodes.inc"
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
-// operator methods. Unary operators are not classes in themselves
-// (they're all opcodes in UnaryOperator) but do have visitors.
-#define OPERATOR(NAME) \
- bool TraverseUnary##NAME(UnaryOperator *S, \
- DataRecursionQueue *Queue = nullptr) { \
- if (!getDerived().shouldTraversePostOrder()) \
- TRY_TO(WalkUpFromUnary##NAME(S)); \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \
- return true; \
- } \
- bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnaryOperator(S)); \
- TRY_TO(VisitUnary##NAME(S)); \
- return true; \
- } \
- bool VisitUnary##NAME(UnaryOperator *S) { return true; }
-
- UNARYOP_LIST()
-#undef OPERATOR
-
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
-// operator methods. Binary operators are not classes in themselves
-// (they're all opcodes in BinaryOperator) but do have visitors.
-#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
- bool TraverseBin##NAME(BINOP_TYPE *S, DataRecursionQueue *Queue = nullptr) { \
- if (!getDerived().shouldTraversePostOrder()) \
- TRY_TO(WalkUpFromBin##NAME(S)); \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLHS()); \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRHS()); \
- return true; \
- } \
- bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
- TRY_TO(VisitBin##NAME(S)); \
- return true; \
- } \
- bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
-
-#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
- BINOP_LIST()
-#undef OPERATOR
-
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
-// assignment methods. Compound assignment operators are not
-// classes in themselves (they're all opcodes in
-// CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME) \
- GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
-
- CAO_LIST()
-#undef OPERATOR
-#undef GENERAL_BINOP_FALLBACK
-
// ---- Methods on Types ----
// FIXME: revamp to take TypeLoc's rather than Types.
@@ -533,8 +487,8 @@ private:
bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
bool TraverseOMPLoopDirective(OMPLoopDirective *S);
bool TraverseOMPClause(OMPClause *C);
-#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
-#include "clang/Basic/OpenMPKinds.def"
+#define OMP_CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C);
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
/// Process clauses with list of variables.
template <typename T> bool VisitOMPClauseList(T *Node);
/// Process clauses with pre-initis.
@@ -548,42 +502,6 @@ private:
template <typename Derived>
bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
DataRecursionQueue *Queue) {
-#define DISPATCH_STMT(NAME, CLASS, VAR) \
- return TRAVERSE_STMT_BASE(NAME, CLASS, VAR, Queue);
-
- // If we have a binary expr, dispatch to the subcode of the binop. A smart
- // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
- // below.
- if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
- switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case BO_##NAME: \
- DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
-
- BINOP_LIST()
-#undef OPERATOR
-#undef BINOP_LIST
-
-#define OPERATOR(NAME) \
- case BO_##NAME##Assign: \
- DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
-
- CAO_LIST()
-#undef OPERATOR
-#undef CAO_LIST
- }
- } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
- switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case UO_##NAME: \
- DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
-
- UNARYOP_LIST()
-#undef OPERATOR
-#undef UNARYOP_LIST
- }
- }
-
// Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
switch (S->getStmtClass()) {
case Stmt::NoStmtClass:
@@ -591,7 +509,7 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
#define ABSTRACT_STMT(STMT)
#define STMT(CLASS, PARENT) \
case Stmt::CLASS##Class: \
- DISPATCH_STMT(CLASS, CLASS, S);
+ return TRAVERSE_STMT_BASE(CLASS, CLASS, S, Queue);
#include "clang/AST/StmtNodes.inc"
}
@@ -602,23 +520,44 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
template <typename Derived>
bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
+ // In pre-order traversal mode, each Traverse##STMT method is responsible for
+ // calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and
+ // does not call the default implementation, the WalkUpFrom callback is not
+ // called. Post-order traversal mode should provide the same behavior
+ // regarding method overrides.
+ //
+ // In post-order traversal mode the Traverse##STMT method, when it receives a
+ // DataRecursionQueue, can't call WalkUpFrom after traversing children because
+ // it only enqueues the children and does not traverse them. TraverseStmt
+ // traverses the enqueued children, and we call WalkUpFrom here.
+ //
+ // However, to make pre-order and post-order modes identical with regards to
+ // whether they call WalkUpFrom at all, we call WalkUpFrom if and only if the
+ // user did not override the Traverse##STMT method. We implement the override
+ // check with isSameMethod calls below.
+
switch (S->getStmtClass()) {
case Stmt::NoStmtClass:
break;
#define ABSTRACT_STMT(STMT)
#define STMT(CLASS, PARENT) \
case Stmt::CLASS##Class: \
- TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); break;
+ if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
+ &Derived::Traverse##CLASS)) { \
+ TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); \
+ } \
+ break;
#define INITLISTEXPR(CLASS, PARENT) \
case Stmt::CLASS##Class: \
- { \
+ if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
+ &Derived::Traverse##CLASS)) { \
auto ILE = static_cast<CLASS *>(S); \
if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE) \
TRY_TO(WalkUpFrom##CLASS(Syn)); \
if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \
TRY_TO(WalkUpFrom##CLASS(Sem)); \
- break; \
- }
+ } \
+ break;
#include "clang/AST/StmtNodes.inc"
}
@@ -668,9 +607,6 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S,
return true;
}
-#define DISPATCH(NAME, CLASS, VAR) \
- return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
-
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
if (T.isNull())
@@ -680,7 +616,8 @@ bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
#define ABSTRACT_TYPE(CLASS, BASE)
#define TYPE(CLASS, BASE) \
case Type::CLASS: \
- DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
+ return getDerived().Traverse##CLASS##Type( \
+ static_cast<CLASS##Type *>(const_cast<Type *>(T.getTypePtr())));
#include "clang/AST/TypeNodes.inc"
}
@@ -730,8 +667,6 @@ bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
return true;
}
-#undef DISPATCH
-
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
NestedNameSpecifier *NNS) {
@@ -1005,6 +940,17 @@ DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
+DEF_TRAVERSE_TYPE(ConstantMatrixType,
+ { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(DependentSizedMatrixType, {
+ if (T->getRowExpr())
+ TRY_TO(TraverseStmt(T->getRowExpr()));
+ if (T->getColumnExpr())
+ TRY_TO(TraverseStmt(T->getColumnExpr()));
+ TRY_TO(TraverseType(T->getElementType()));
+})
+
DEF_TRAVERSE_TYPE(FunctionNoProtoType,
{ TRY_TO(TraverseType(T->getReturnType())); })
@@ -1039,7 +985,13 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
TRY_TO(TraverseType(T->getUnderlyingType()));
})
-DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
+DEF_TRAVERSE_TYPE(AutoType, {
+ TRY_TO(TraverseType(T->getDeducedType()));
+ if (T->isConstrained()) {
+ TRY_TO(TraverseDecl(T->getTypeConstraintConcept()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ }
+})
DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
TRY_TO(TraverseTemplateName(T->getTemplateName()));
TRY_TO(TraverseType(T->getDeducedType()));
@@ -1108,6 +1060,10 @@ DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
+DEF_TRAVERSE_TYPE(ExtIntType, {})
+DEF_TRAVERSE_TYPE(DependentExtIntType,
+ { TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
+
#undef DEF_TRAVERSE_TYPE
// ----------------- TypeLoc traversal -----------------
@@ -1120,10 +1076,17 @@ DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
template <typename Derived> \
bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
- if (getDerived().shouldWalkTypesOfTypeLocs()) \
- TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
- TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
+ if (!getDerived().shouldTraversePostOrder()) { \
+ TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
+ if (getDerived().shouldWalkTypesOfTypeLocs()) \
+ TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
+ } \
{ CODE; } \
+ if (getDerived().shouldTraversePostOrder()) { \
+ TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
+ if (getDerived().shouldWalkTypesOfTypeLocs()) \
+ TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
+ } \
return true; \
}
@@ -1192,22 +1155,22 @@ bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
+ TRY_TO(TraverseArrayTypeLocHelper(TL));
})
DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
+ TRY_TO(TraverseArrayTypeLocHelper(TL));
})
DEF_TRAVERSE_TYPELOC(VariableArrayType, {
TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
+ TRY_TO(TraverseArrayTypeLocHelper(TL));
})
DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
+ TRY_TO(TraverseArrayTypeLocHelper(TL));
})
DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, {
@@ -1240,6 +1203,18 @@ DEF_TRAVERSE_TYPELOC(ExtVectorType, {
TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
})
+DEF_TRAVERSE_TYPELOC(ConstantMatrixType, {
+ TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
+ TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+DEF_TRAVERSE_TYPELOC(DependentSizedMatrixType, {
+ TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
+ TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
{ TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
@@ -1286,6 +1261,12 @@ DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
DEF_TRAVERSE_TYPELOC(AutoType, {
TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+ if (TL.isConstrained()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo()));
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
})
DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
@@ -1365,6 +1346,11 @@ DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
+DEF_TRAVERSE_TYPELOC(ExtIntType, {})
+DEF_TRAVERSE_TYPELOC(DependentExtIntType, {
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
+})
+
#undef DEF_TRAVERSE_TYPELOC
// ----------------- Decl traversal -----------------
@@ -1973,6 +1959,8 @@ DEF_TRAVERSE_DECL(BindingDecl, {
DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
+DEF_TRAVERSE_DECL(MSGuidDecl, {})
+
DEF_TRAVERSE_DECL(FieldDecl, {
TRY_TO(TraverseDeclaratorHelper(D));
if (D->isBitField())
@@ -2049,11 +2037,11 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
}
}
- bool VisitBody = D->isThisDeclarationADefinition();
- // If a method is set to default outside the class definition the compiler
- // generates the method body and adds it to the AST.
- if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
- VisitBody &= !MD->isDefaulted() || getDerived().shouldVisitImplicitCode();
+ bool VisitBody =
+ D->isThisDeclarationADefinition() &&
+ // Don't visit the function body if the function definition is generated
+ // by clang.
+ (!D->isDefaulted() || getDerived().shouldVisitImplicitCode());
if (VisitBody) {
TRY_TO(TraverseStmt(D->getBody())); // Function body.
@@ -2138,6 +2126,8 @@ DEF_TRAVERSE_DECL(ParmVarDecl, {
TRY_TO(TraverseStmt(D->getDefaultArg()));
})
+DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {})
+
#undef DEF_TRAVERSE_DECL
// ----------------- Stmt traversal -----------------
@@ -2164,8 +2154,13 @@ DEF_TRAVERSE_DECL(ParmVarDecl, {
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
} \
} \
- if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) \
+ /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \
+ * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \
+ * children, PostVisitStmt will call WalkUpFrom after we are done visiting \
+ * children. */ \
+ if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \
TRY_TO(WalkUpFrom##STMT(S)); \
+ } \
return ReturnValue; \
}
@@ -2299,6 +2294,10 @@ DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
})
+DEF_TRAVERSE_STMT(CXXAddrspaceCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
DEF_TRAVERSE_STMT(CXXConstCastExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
})
@@ -2332,6 +2331,9 @@ bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
for (Stmt *SubStmt : S->children()) {
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt);
}
+
+ if (!Queue && getDerived().shouldTraversePostOrder())
+ TRY_TO(WalkUpFromInitListExpr(S));
}
return true;
}
@@ -2528,7 +2530,10 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
// over the children.
DEF_TRAVERSE_STMT(AddrLabelExpr, {})
DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
+DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {})
DEF_TRAVERSE_STMT(OMPArraySectionExpr, {})
+DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {})
+DEF_TRAVERSE_STMT(OMPIteratorExpr, {})
DEF_TRAVERSE_STMT(BlockExpr, {
TRY_TO(TraverseDecl(S->getBlockDecl()));
@@ -2646,6 +2651,7 @@ DEF_TRAVERSE_STMT(CXXRewrittenBinaryOperator, {
})
DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
DEF_TRAVERSE_STMT(TypoExpr, {})
+DEF_TRAVERSE_STMT(RecoveryExpr, {})
DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
// These operators (all of them) do not need any action except
@@ -2709,6 +2715,28 @@ DEF_TRAVERSE_STMT(ConceptSpecializationExpr, {
TRY_TO(TraverseConceptReference(*S));
})
+DEF_TRAVERSE_STMT(RequiresExpr, {
+ TRY_TO(TraverseDecl(S->getBody()));
+ for (ParmVarDecl *Parm : S->getLocalParameters())
+ TRY_TO(TraverseDecl(Parm));
+ for (concepts::Requirement *Req : S->getRequirements())
+ if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
+ if (!TypeReq->isSubstitutionFailure())
+ TRY_TO(TraverseTypeLoc(TypeReq->getType()->getTypeLoc()));
+ } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
+ if (!ExprReq->isExprSubstitutionFailure())
+ TRY_TO(TraverseStmt(ExprReq->getExpr()));
+ auto &RetReq = ExprReq->getReturnTypeRequirement();
+ if (RetReq.isTypeConstraint())
+ TRY_TO(TraverseTemplateParameterListHelper(
+ RetReq.getTypeConstraintTemplateParameterList()));
+ } else {
+ auto *NestedReq = cast<concepts::NestedRequirement>(Req);
+ if (!NestedReq->isSubstitutionFailure())
+ TRY_TO(TraverseStmt(NestedReq->getConstraintExpr()));
+ }
+})
+
// These literals (all of them) do not need any action.
DEF_TRAVERSE_STMT(IntegerLiteral, {})
DEF_TRAVERSE_STMT(FixedPointLiteral, {})
@@ -2805,6 +2833,12 @@ DEF_TRAVERSE_STMT(OMPCancelDirective,
DEF_TRAVERSE_STMT(OMPFlushDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPDepobjDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPScanDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPOrderedDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2904,16 +2938,15 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
if (!C)
return true;
switch (C->getClauseKind()) {
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_##Name: \
+#define OMP_CLAUSE_CLASS(Enum, Str, Class) \
+ case llvm::omp::Clause::Enum: \
TRY_TO(Visit##Class(static_cast<Class *>(C))); \
break;
-#include "clang/Basic/OpenMPKinds.def"
- case OMPC_threadprivate:
- case OMPC_uniform:
- case OMPC_device_type:
- case OMPC_match:
- case OMPC_unknown:
+#define OMP_CLAUSE_NO_CLASS(Enum, Str) \
+ case llvm::omp::Clause::Enum: \
+ break;
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+ default:
break;
}
return true;
@@ -3085,6 +3118,26 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAcqRelClause(OMPAcqRelClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAcquireClause(OMPAcquireClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPReleaseClause(OMPReleaseClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPRelaxedClause(OMPRelaxedClause *) {
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
return true;
}
@@ -3100,6 +3153,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPNogroupClause(OMPNogroupClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDestroyClause(OMPDestroyClause *) {
+ return true;
+}
+
+template <typename Derived>
template <typename T>
bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
for (auto *E : Node->varlists()) {
@@ -3109,6 +3167,20 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPInclusiveClause(
+ OMPInclusiveClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPExclusiveClause(
+ OMPExclusiveClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
TRY_TO(VisitOMPClauseList(C));
for (auto *E : C->private_copies()) {
@@ -3235,6 +3307,17 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
for (auto *E : C->reduction_ops()) {
TRY_TO(TraverseStmt(E));
}
+ if (C->getModifier() == OMPC_REDUCTION_inscan) {
+ for (auto *E : C->copy_ops()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->copy_array_temps()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->copy_array_elems()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ }
return true;
}
@@ -3291,6 +3374,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDepobjClause(OMPDepobjClause *C) {
+ TRY_TO(TraverseStmt(C->getDepobj()));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
TRY_TO(VisitOMPClauseList(C));
return true;
@@ -3389,6 +3478,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPUseDevicePtrClause(
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUseDeviceAddrClause(
+ OMPUseDeviceAddrClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPIsDevicePtrClause(
OMPIsDevicePtrClause *C) {
TRY_TO(VisitOMPClauseList(C));
@@ -3405,6 +3501,37 @@ bool RecursiveASTVisitor<Derived>::VisitOMPNontemporalClause(
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPOrderClause(OMPOrderClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDetachClause(OMPDetachClause *C) {
+ TRY_TO(TraverseStmt(C->getEventHandler()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUsesAllocatorsClause(
+ OMPUsesAllocatorsClause *C) {
+ for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
+ const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
+ TRY_TO(TraverseStmt(Data.Allocator));
+ TRY_TO(TraverseStmt(Data.AllocatorTraits));
+ }
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAffinityClause(
+ OMPAffinityClause *C) {
+ TRY_TO(TraverseStmt(C->getModifier()));
+ for (Expr *E : C->varlists())
+ TRY_TO(TraverseStmt(E));
+ return true;
+}
+
// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
// returning decls or qualtypes or nestednamespecifier -- though I'm
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index eaacb1a5b252..d3fad58fcf59 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -14,12 +14,14 @@
#define LLVM_CLANG_AST_STMT_H
#include "clang/AST/DeclGroup.h"
+#include "clang/AST/DependenceFlags.h"
#include "clang/AST/StmtIterator.h"
#include "clang/Basic/CapturedStmt.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
@@ -98,14 +100,8 @@ protected:
/// The statement class.
unsigned sClass : 8;
-
- /// This bit is set only for the Stmts that are the structured-block of
- /// OpenMP executable directives. Directives that have a structured block
- /// are called "non-standalone" directives.
- /// I.e. those returned by OMPExecutableDirective::getStructuredBlock().
- unsigned IsOMPStructuredBlock : 1;
};
- enum { NumStmtBits = 9 };
+ enum { NumStmtBits = 8 };
class NullStmtBitfields {
friend class ASTStmtReader;
@@ -315,12 +311,9 @@ protected:
unsigned ValueKind : 2;
unsigned ObjectKind : 3;
- unsigned TypeDependent : 1;
- unsigned ValueDependent : 1;
- unsigned InstantiationDependent : 1;
- unsigned ContainsUnexpandedParameterPack : 1;
+ unsigned /*ExprDependence*/ Dependent : llvm::BitWidth<ExprDependence>;
};
- enum { NumExprBits = NumStmtBits + 9 };
+ enum { NumExprBits = NumStmtBits + 5 + llvm::BitWidth<ExprDependence> };
class ConstantExprBitfields {
friend class ASTStmtReader;
@@ -329,24 +322,27 @@ protected:
unsigned : NumExprBits;
- /// The kind of result that is trail-allocated.
+ /// The kind of result that is tail-allocated.
unsigned ResultKind : 2;
- /// Kind of Result as defined by APValue::Kind
+ /// The kind of Result as defined by APValue::Kind.
unsigned APValueKind : 4;
- /// When ResultKind == RSK_Int64. whether the trail-allocated integer is
- /// signed.
+ /// When ResultKind == RSK_Int64, true if the tail-allocated integer is
+ /// unsigned.
unsigned IsUnsigned : 1;
- /// When ResultKind == RSK_Int64. the BitWidth of the trail-allocated
- /// integer. 7 bits because it is the minimal number of bit to represent a
- /// value from 0 to 64 (the size of the trail-allocated number).
+ /// When ResultKind == RSK_Int64. the BitWidth of the tail-allocated
+ /// integer. 7 bits because it is the minimal number of bits to represent a
+ /// value from 0 to 64 (the size of the tail-allocated integer).
unsigned BitWidth : 7;
- /// When ResultKind == RSK_APValue. Wether the ASTContext will cleanup the
- /// destructor on the trail-allocated APValue.
+ /// When ResultKind == RSK_APValue, true if the ASTContext will cleanup the
+ /// tail-allocated APValue.
unsigned HasCleanup : 1;
+
+ /// True if this ConstantExpr was created for immediate invocation.
+ unsigned IsImmediateInvocation : 1;
};
class PredefinedExprBitfields {
@@ -431,6 +427,11 @@ protected:
unsigned Opc : 5;
unsigned CanOverflow : 1;
+ //
+ /// This is only meaningful for operations on floating point
+ /// types when additional values need to be in trailing storage.
+ /// It is 0 otherwise.
+ unsigned HasFPFeatures : 1;
SourceLocation Loc;
};
@@ -444,8 +445,9 @@ protected:
unsigned IsType : 1; // true if operand is a type, false if an expression.
};
- class ArraySubscriptExprBitfields {
+ class ArrayOrMatrixSubscriptExprBitfields {
friend class ArraySubscriptExpr;
+ friend class MatrixSubscriptExpr;
unsigned : NumExprBits;
@@ -529,8 +531,9 @@ protected:
unsigned Opc : 6;
/// This is only meaningful for operations on floating point
- /// types and 0 otherwise.
- unsigned FPFeatures : 3;
+ /// types when additional values need to be in trailing storage.
+ /// It is 0 otherwise.
+ unsigned HasFPFeatures : 1;
SourceLocation OpLoc;
};
@@ -588,6 +591,18 @@ protected:
unsigned Kind : 2;
};
+ class StmtExprBitfields {
+ friend class ASTStmtReader;
+ friend class StmtExpr;
+
+ unsigned : NumExprBits;
+
+ /// The number of levels of template parameters enclosing this statement
+ /// expression. Used to determine if a statement expression remains
+ /// dependent after instantiation.
+ unsigned TemplateDepth;
+ };
+
//===--- C++ Expression bitfields classes ---===//
class CXXOperatorCallExprBitfields {
@@ -599,9 +614,6 @@ protected:
/// The kind of this overloaded operator. One of the enumerator
/// value of OverloadedOperatorKind.
unsigned OperatorKind : 6;
-
- // Only meaningful for floating point types.
- unsigned FPFeatures : 3;
};
class CXXRewrittenBinaryOperatorBitfields {
@@ -760,8 +772,10 @@ protected:
/// the trait evaluated true or false.
unsigned Value : 1;
- /// The number of arguments to this type trait.
- unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
+ /// The number of arguments to this type trait. According to [implimits]
+ /// 8 bits would be enough, but we require (and test for) at least 16 bits
+ /// to mirror FunctionType.
+ unsigned NumArgs;
};
class DependentScopeDeclRefExprBitfields {
@@ -910,6 +924,39 @@ protected:
SourceLocation NameLoc;
};
+ class LambdaExprBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class LambdaExpr;
+
+ unsigned : NumExprBits;
+
+ /// The default capture kind, which is a value of type
+ /// LambdaCaptureDefault.
+ unsigned CaptureDefault : 2;
+
+ /// Whether this lambda had an explicit parameter list vs. an
+ /// implicit (and empty) parameter list.
+ unsigned ExplicitParams : 1;
+
+ /// Whether this lambda had the result type explicitly specified.
+ unsigned ExplicitResultType : 1;
+
+ /// The number of captures.
+ unsigned NumCaptures : 16;
+ };
+
+ class RequiresExprBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class RequiresExpr;
+
+ unsigned : NumExprBits;
+
+ unsigned IsSatisfied : 1;
+ SourceLocation RequiresKWLoc;
+ };
+
//===--- C++ Coroutines TS bitfields classes ---===//
class CoawaitExprBitfields {
@@ -974,7 +1021,7 @@ protected:
CharacterLiteralBitfields CharacterLiteralBits;
UnaryOperatorBitfields UnaryOperatorBits;
UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
- ArraySubscriptExprBitfields ArraySubscriptExprBits;
+ ArrayOrMatrixSubscriptExprBitfields ArrayOrMatrixSubscriptExprBits;
CallExprBitfields CallExprBits;
MemberExprBitfields MemberExprBits;
CastExprBitfields CastExprBits;
@@ -985,6 +1032,9 @@ protected:
PseudoObjectExprBitfields PseudoObjectExprBits;
SourceLocExprBitfields SourceLocExprBits;
+ // GNU Extensions.
+ StmtExprBitfields StmtExprBits;
+
// C++ Expressions
CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
CXXRewrittenBinaryOperatorBitfields CXXRewrittenBinaryOperatorBits;
@@ -1008,6 +1058,8 @@ protected:
UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
CXXNoexceptExprBitfields CXXNoexceptExprBits;
SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
+ LambdaExprBitfields LambdaExprBits;
+ RequiresExprBitfields RequiresExprBits;
// C++ Coroutines TS expressions
CoawaitExprBitfields CoawaitBits;
@@ -1090,7 +1142,6 @@ public:
static_assert(sizeof(*this) % alignof(void *) == 0,
"Insufficient alignment!");
StmtBits.sClass = SC;
- StmtBits.IsOMPStructuredBlock = false;
if (StatisticsEnabled) Stmt::addStmtClass(SC);
}
@@ -1100,11 +1151,6 @@ public:
const char *getStmtClassName() const;
- bool isOMPStructuredBlock() const { return StmtBits.IsOMPStructuredBlock; }
- void setIsOMPStructuredBlock(bool IsOMPStructuredBlock) {
- StmtBits.IsOMPStructuredBlock = IsOMPStructuredBlock;
- }
-
/// SourceLocation tokens are not useful in isolation - they are low level
/// value objects created/interpreted by SourceManager. We assume AST
/// clients will have a pointer to the respective SourceManager.
@@ -1120,9 +1166,7 @@ public:
/// Dumps the specified AST fragment and all subtrees to
/// \c llvm::errs().
void dump() const;
- void dump(SourceManager &SM) const;
- void dump(raw_ostream &OS, SourceManager &SM) const;
- void dump(raw_ostream &OS) const;
+ void dump(raw_ostream &OS, const ASTContext &Context) const;
/// \return Unique reproducible object identifier
int64_t getID(const ASTContext &Context) const;
@@ -2233,6 +2277,8 @@ class WhileStmt final : public Stmt,
enum { VarOffset = 0, BodyOffsetFromCond = 1 };
enum { NumMandatoryStmtPtr = 2 };
+ SourceLocation LParenLoc, RParenLoc;
+
unsigned varOffset() const { return VarOffset; }
unsigned condOffset() const { return VarOffset + hasVarStorage(); }
unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }
@@ -2243,7 +2289,8 @@ class WhileStmt final : public Stmt,
/// Build a while statement.
WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body,
- SourceLocation WL);
+ SourceLocation WL, SourceLocation LParenLoc,
+ SourceLocation RParenLoc);
/// Build an empty while statement.
explicit WhileStmt(EmptyShell Empty, bool HasVar);
@@ -2251,7 +2298,8 @@ class WhileStmt final : public Stmt,
public:
/// Create a while statement.
static WhileStmt *Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
- Stmt *Body, SourceLocation WL);
+ Stmt *Body, SourceLocation WL,
+ SourceLocation LParenLoc, SourceLocation RParenLoc);
/// Create an empty while statement optionally with storage for
/// a condition variable.
@@ -2315,6 +2363,11 @@ public:
SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; }
void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; }
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+ void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
SourceLocation getBeginLoc() const { return getWhileLoc(); }
SourceLocation getEndLoc() const LLVM_READONLY {
return getBody()->getEndLoc();
@@ -3017,7 +3070,7 @@ public:
}
IdentifierInfo *getLabelIdentifier(unsigned i) const {
- return Names[i + NumInputs];
+ return Names[i + NumOutputs + NumInputs];
}
AddrLabelExpr *getLabelExpr(unsigned i) const;
@@ -3028,11 +3081,11 @@ public:
using labels_const_range = llvm::iterator_range<const_labels_iterator>;
labels_iterator begin_labels() {
- return &Exprs[0] + NumInputs;
+ return &Exprs[0] + NumOutputs + NumInputs;
}
labels_iterator end_labels() {
- return &Exprs[0] + NumInputs + NumLabels;
+ return &Exprs[0] + NumOutputs + NumInputs + NumLabels;
}
labels_range labels() {
@@ -3040,11 +3093,11 @@ public:
}
const_labels_iterator begin_labels() const {
- return &Exprs[0] + NumInputs;
+ return &Exprs[0] + NumOutputs + NumInputs;
}
const_labels_iterator end_labels() const {
- return &Exprs[0] + NumInputs + NumLabels;
+ return &Exprs[0] + NumOutputs + NumInputs + NumLabels;
}
labels_const_range labels() const {
diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h
index 65f0afece224..bd87eafc9034 100644
--- a/clang/include/clang/AST/StmtOpenMP.h
+++ b/clang/include/clang/AST/StmtOpenMP.h
@@ -356,6 +356,9 @@ public:
///
class OMPParallelDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
/// true if the construct has inner cancel directive.
bool HasCancel;
@@ -381,6 +384,9 @@ class OMPParallelDirective : public OMPExecutableDirective {
SourceLocation(), NumClauses, 1),
HasCancel(false) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
@@ -392,11 +398,14 @@ public:
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement associated with the directive.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
/// \param HasCancel true if this directive has inner cancel directive.
///
static OMPParallelDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
+ bool HasCancel);
/// Creates an empty directive with the place for \a N clauses.
///
@@ -406,6 +415,10 @@ public:
static OMPParallelDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
@@ -1258,7 +1271,9 @@ public:
///
class OMPForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
-
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
/// true if current directive has inner cancel directive.
bool HasCancel;
@@ -1286,6 +1301,9 @@ class OMPForDirective : public OMPLoopDirective {
NumClauses),
HasCancel(false) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
@@ -1299,13 +1317,15 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
/// \param HasCancel true if current directive has inner cancel directive.
///
static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs,
- bool HasCancel);
+ Expr *TaskRedRef, bool HasCancel);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -1317,6 +1337,10 @@ public:
static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
unsigned CollapsedNum, EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
@@ -1403,6 +1427,9 @@ public:
class OMPSectionsDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
/// true if current directive has inner cancel directive.
bool HasCancel;
@@ -1429,6 +1456,9 @@ class OMPSectionsDirective : public OMPExecutableDirective {
SourceLocation(), NumClauses, 1),
HasCancel(false) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
@@ -1440,11 +1470,14 @@ public:
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
/// \param HasCancel true if current directive has inner directive.
///
static OMPSectionsDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
+ bool HasCancel);
/// Creates an empty directive with the place for \a NumClauses
/// clauses.
@@ -1455,6 +1488,10 @@ public:
static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
@@ -1715,6 +1752,9 @@ public:
class OMPParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
/// true if current region has inner cancel directive.
bool HasCancel;
@@ -1743,6 +1783,9 @@ class OMPParallelForDirective : public OMPLoopDirective {
SourceLocation(), CollapsedNum, NumClauses),
HasCancel(false) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
@@ -1756,12 +1799,15 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
/// \param HasCancel true if current directive has inner cancel directive.
///
static OMPParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
+ bool HasCancel);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -1775,6 +1821,10 @@ public:
unsigned CollapsedNum,
EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
@@ -1863,6 +1913,10 @@ public:
class OMPParallelMasterDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
+
OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses)
: OMPExecutableDirective(this, OMPParallelMasterDirectiveClass,
@@ -1875,6 +1929,9 @@ class OMPParallelMasterDirective : public OMPExecutableDirective {
SourceLocation(), SourceLocation(), NumClauses,
1) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+
public:
/// Creates directive with a list of \a Clauses.
///
@@ -1883,10 +1940,12 @@ public:
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
///
static OMPParallelMasterDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
/// Creates an empty directive with the place for \a NumClauses
/// clauses.
@@ -1897,6 +1956,10 @@ public:
static OMPParallelMasterDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelMasterDirectiveClass;
}
@@ -1914,6 +1977,9 @@ public:
class OMPParallelSectionsDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
/// true if current directive has inner cancel directive.
bool HasCancel;
@@ -1941,6 +2007,9 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective {
1),
HasCancel(false) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
@@ -1952,11 +2021,14 @@ public:
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
/// \param HasCancel true if current directive has inner cancel directive.
///
static OMPParallelSectionsDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
+ bool HasCancel);
/// Creates an empty directive with the place for \a NumClauses
/// clauses.
@@ -1967,6 +2039,10 @@ public:
static OMPParallelSectionsDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
@@ -2314,6 +2390,64 @@ public:
}
};
+/// This represents '#pragma omp depobj' directive.
+///
+/// \code
+/// #pragma omp depobj(a) depend(in:x,y)
+/// \endcode
+/// In this example directive '#pragma omp depobj' initializes a depobj object
+/// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
+class OMPDepobjDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPDepobjDirectiveClass,
+ llvm::omp::OMPD_depobj, StartLoc, EndLoc,
+ NumClauses, 0) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPDepobjDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPDepobjDirectiveClass,
+ llvm::omp::OMPD_depobj, SourceLocation(),
+ SourceLocation(), NumClauses, 0) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ ///
+ static OMPDepobjDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses);
+
+ /// Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPDepobjDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp ordered' directive.
///
/// \code
@@ -2747,6 +2881,12 @@ public:
///
class OMPTargetParallelDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel = false;
+
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
@@ -2769,6 +2909,11 @@ class OMPTargetParallelDirective : public OMPExecutableDirective {
SourceLocation(), SourceLocation(), NumClauses,
/*NumChildren=*/1) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
+
public:
/// Creates directive with a list of \a Clauses.
///
@@ -2777,10 +2922,14 @@ public:
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
+ /// \param HasCancel true if this directive has inner cancel directive.
///
static OMPTargetParallelDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
+ bool HasCancel);
/// Creates an empty directive with the place for \a NumClauses
/// clauses.
@@ -2791,6 +2940,13 @@ public:
static OMPTargetParallelDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTargetParallelDirectiveClass;
}
@@ -2808,6 +2964,9 @@ public:
class OMPTargetParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
/// true if current region has inner cancel directive.
bool HasCancel;
@@ -2837,6 +2996,9 @@ class OMPTargetParallelForDirective : public OMPLoopDirective {
SourceLocation(), CollapsedNum, NumClauses),
HasCancel(false) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
@@ -2850,12 +3012,15 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
/// \param HasCancel true if current directive has inner cancel directive.
///
static OMPTargetParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
+ bool HasCancel);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -2869,6 +3034,10 @@ public:
unsigned CollapsedNum,
EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
@@ -3070,6 +3239,9 @@ public:
///
class OMPTaskLoopDirective : public OMPLoopDirective {
friend class ASTStmtReader;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel;
+
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
@@ -3081,7 +3253,8 @@ class OMPTaskLoopDirective : public OMPLoopDirective {
unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPTaskLoopDirectiveClass,
llvm::omp::OMPD_taskloop, StartLoc, EndLoc,
- CollapsedNum, NumClauses) {}
+ CollapsedNum, NumClauses),
+ HasCancel(false) {}
/// Build an empty directive.
///
@@ -3091,7 +3264,11 @@ class OMPTaskLoopDirective : public OMPLoopDirective {
explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPTaskLoopDirectiveClass,
llvm::omp::OMPD_taskloop, SourceLocation(),
- SourceLocation(), CollapsedNum, NumClauses) {}
+ SourceLocation(), CollapsedNum, NumClauses),
+ HasCancel(false) {}
+
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// Creates directive with a list of \a Clauses.
@@ -3103,11 +3280,12 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if this directive has inner cancel directive.
///
static OMPTaskLoopDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -3120,6 +3298,9 @@ public:
unsigned NumClauses,
unsigned CollapsedNum, EmptyShell);
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTaskLoopDirectiveClass;
}
@@ -3203,6 +3384,9 @@ public:
///
class OMPMasterTaskLoopDirective : public OMPLoopDirective {
friend class ASTStmtReader;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel;
+
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
@@ -3214,7 +3398,8 @@ class OMPMasterTaskLoopDirective : public OMPLoopDirective {
unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass,
llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
- CollapsedNum, NumClauses) {}
+ CollapsedNum, NumClauses),
+ HasCancel(false) {}
/// Build an empty directive.
///
@@ -3225,7 +3410,11 @@ class OMPMasterTaskLoopDirective : public OMPLoopDirective {
unsigned NumClauses)
: OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass,
llvm::omp::OMPD_master_taskloop, SourceLocation(),
- SourceLocation(), CollapsedNum, NumClauses) {}
+ SourceLocation(), CollapsedNum, NumClauses),
+ HasCancel(false) {}
+
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// Creates directive with a list of \a Clauses.
@@ -3237,11 +3426,12 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if this directive has inner cancel directive.
///
static OMPMasterTaskLoopDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -3255,6 +3445,9 @@ public:
unsigned CollapsedNum,
EmptyShell);
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
}
@@ -3339,6 +3532,9 @@ public:
///
class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective {
friend class ASTStmtReader;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel;
+
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
@@ -3351,7 +3547,8 @@ class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective {
unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass,
llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
- EndLoc, CollapsedNum, NumClauses) {}
+ EndLoc, CollapsedNum, NumClauses),
+ HasCancel(false) {}
/// Build an empty directive.
///
@@ -3363,7 +3560,11 @@ class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective {
: OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass,
llvm::omp::OMPD_parallel_master_taskloop,
SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses) {}
+ NumClauses),
+ HasCancel(false) {}
+
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// Creates directive with a list of \a Clauses.
@@ -3375,11 +3576,12 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if this directive has inner cancel directive.
///
static OMPParallelMasterTaskLoopDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -3393,6 +3595,9 @@ public:
unsigned CollapsedNum,
EmptyShell);
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
}
@@ -3605,6 +3810,9 @@ public:
///
class OMPDistributeParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
/// true if the construct has inner cancel directive.
bool HasCancel = false;
@@ -3636,6 +3844,9 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective {
NumClauses),
HasCancel(false) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
@@ -3649,12 +3860,15 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
/// \param HasCancel true if this directive has inner cancel directive.
///
static OMPDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
+ bool HasCancel);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -3668,6 +3882,10 @@ public:
unsigned CollapsedNum,
EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
@@ -4170,6 +4388,9 @@ public:
///
class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
/// true if the construct has inner cancel directive.
bool HasCancel = false;
@@ -4202,6 +4423,9 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
NumClauses),
HasCancel(false) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
@@ -4215,12 +4439,15 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
/// \param HasCancel true if this directive has inner cancel directive.
///
static OMPTeamsDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
+ bool HasCancel);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
@@ -4232,6 +4459,10 @@ public:
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
@@ -4379,6 +4610,9 @@ public:
class OMPTargetTeamsDistributeParallelForDirective final
: public OMPLoopDirective {
friend class ASTStmtReader;
+ /// Special reference expression for handling task reduction. Used to store
+ /// the taskgroup descriptor returned by the runtime functions.
+ Expr *TaskRedRef = nullptr;
/// true if the construct has inner cancel directive.
bool HasCancel = false;
@@ -4412,6 +4646,9 @@ class OMPTargetTeamsDistributeParallelForDirective final
SourceLocation(), SourceLocation(), CollapsedNum, NumClauses),
HasCancel(false) {}
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; }
+
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
@@ -4425,12 +4662,15 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
/// \param HasCancel true if this directive has inner cancel directive.
///
static OMPTargetTeamsDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
+ bool HasCancel);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
@@ -4442,6 +4682,10 @@ public:
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell);
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() { return TaskRedRef; }
+ const Expr *getTaskReductionRefExpr() const { return TaskRedRef; }
+
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
@@ -4594,6 +4838,63 @@ public:
}
};
+/// This represents '#pragma omp scan' directive.
+///
+/// \code
+/// #pragma omp scan inclusive(a)
+/// \endcode
+/// In this example directive '#pragma omp scan' has clause 'inclusive' with
+/// list item 'a'.
+class OMPScanDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPScanDirectiveClass,
+ llvm::omp::OMPD_scan, StartLoc, EndLoc,
+ NumClauses, 0) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPScanDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPScanDirectiveClass,
+ llvm::omp::OMPD_scan, SourceLocation(),
+ SourceLocation(), NumClauses, 0) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses (only single OMPFlushClause clause is
+ /// allowed).
+ ///
+ static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses);
+
+ /// Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPScanDirectiveClass;
+ }
+};
+
} // end namespace clang
#endif
diff --git a/clang/include/clang/AST/StmtVisitor.h b/clang/include/clang/AST/StmtVisitor.h
index d3be93d228cc..3e5155199eac 100644
--- a/clang/include/clang/AST/StmtVisitor.h
+++ b/clang/include/clang/AST/StmtVisitor.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_AST_STMTVISITOR_H
#define LLVM_CLANG_AST_STMTVISITOR_H
+#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h
index 058a5bc0a067..51fd8ba51034 100644
--- a/clang/include/clang/AST/TemplateBase.h
+++ b/clang/include/clang/AST/TemplateBase.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
#define LLVM_CLANG_AST_TEMPLATEBASE_H
+#include "clang/AST/DependenceFlags.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
@@ -81,8 +82,7 @@ public:
/// The template argument is an expression, and we've not resolved it to one
/// of the other forms yet, either because it's dependent or because we're
/// representing a non-canonical template argument (for instance, in a
- /// TemplateSpecializationType). Also used to represent a non-dependent
- /// __uuidof expression (a Microsoft extension).
+ /// TemplateSpecializationType).
Expression,
/// The template argument is actually a parameter pack. Arguments are stored
@@ -236,6 +236,8 @@ public:
/// Determine whether this template argument has no value.
bool isNull() const { return getKind() == Null; }
+ TemplateArgumentDependence getDependence() const;
+
/// Whether this template argument is dependent on a template
/// parameter such that its result can change from one instantiation to
/// another.
@@ -637,7 +639,7 @@ public:
}
static const ASTTemplateArgumentListInfo *
- Create(ASTContext &C, const TemplateArgumentListInfo &List);
+ Create(const ASTContext &C, const TemplateArgumentListInfo &List);
};
/// Represents an explicit template argument list in C++, e.g.,
@@ -666,11 +668,13 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo {
void initializeFrom(SourceLocation TemplateKWLoc,
const TemplateArgumentListInfo &List,
TemplateArgumentLoc *OutArgArray);
+ // FIXME: The parameter Deps is the result populated by this method, the
+ // caller doesn't need it since it is populated by computeDependence. remove
+ // it.
void initializeFrom(SourceLocation TemplateKWLoc,
const TemplateArgumentListInfo &List,
- TemplateArgumentLoc *OutArgArray, bool &Dependent,
- bool &InstantiationDependent,
- bool &ContainsUnexpandedParameterPack);
+ TemplateArgumentLoc *OutArgArray,
+ TemplateArgumentDependence &Deps);
void initializeFrom(SourceLocation TemplateKWLoc);
void copyInto(const TemplateArgumentLoc *ArgArray,
@@ -702,6 +706,11 @@ inline const TemplateArgument &
return getArgs()[Idx];
}
+inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
+ assert(Idx < getNumArgs() && "Template argument out of range");
+ return getArgs()[Idx];
+}
+
} // namespace clang
#endif // LLVM_CLANG_AST_TEMPLATEBASE_H
diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h
index cbbcbf6af8ab..9bcf2838dcf1 100644
--- a/clang/include/clang/AST/TemplateName.h
+++ b/clang/include/clang/AST/TemplateName.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
#define LLVM_CLANG_AST_TEMPLATENAME_H
+#include "clang/AST/DependenceFlags.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/FoldingSet.h"
@@ -295,6 +296,8 @@ public:
/// the template, including any default template arguments.
TemplateName getNameToSubstitute() const;
+ TemplateNameDependence getDependence() const;
+
/// Determines whether this is a dependent template name.
bool isDependent() const;
@@ -559,7 +562,7 @@ struct PointerLikeTypeTraits<clang::TemplateName> {
}
// No bits are available!
- enum { NumLowBitsAvailable = 0 };
+ static constexpr int NumLowBitsAvailable = 0;
};
} // namespace llvm.
diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h
index d293ea190aa4..b4cfb5a380d1 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -22,10 +22,13 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TemplateArgumentVisitor.h"
+#include "clang/AST/Type.h"
#include "clang/AST/TypeVisitor.h"
namespace clang {
+class APValue;
+
class TextTreeStructure {
raw_ostream &OS;
const bool ShowColors;
@@ -68,7 +71,7 @@ public:
// We need to capture an owning-string in the lambda because the lambda
// is invoked in a deferred manner.
- std::string LabelStr = Label;
+ std::string LabelStr(Label);
auto DumpWithIndent = [this, DoAddChild, LabelStr](bool IsLastChild) {
// Print out the appropriate tree structure and work out the prefix for
// children of this node. For instance:
@@ -139,19 +142,29 @@ class TextNodeDumper
const char *LastLocFilename = "";
unsigned LastLocLine = ~0U;
- const SourceManager *SM;
+ /// \p Context, \p SM, and \p Traits can be null. This is because we want
+ /// to be able to call \p dump() in a debugger without having to pass the
+ /// \p ASTContext to \p dump. Not all parts of the AST dump output will be
+ /// available without the \p ASTContext.
+ const ASTContext *Context = nullptr;
+ const SourceManager *SM = nullptr;
/// The policy to use for printing; can be defaulted.
- PrintingPolicy PrintPolicy;
+ PrintingPolicy PrintPolicy = LangOptions();
- const comments::CommandTraits *Traits;
+ const comments::CommandTraits *Traits = nullptr;
const char *getCommandName(unsigned CommandID);
+ void dumpAPValueChildren(const APValue &Value, QualType Ty,
+ const APValue &(*IdxToChildFun)(const APValue &,
+ unsigned),
+ unsigned NumChildren, StringRef LabelSingular,
+ StringRef LabelPlurial);
+
public:
- TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM,
- const PrintingPolicy &PrintPolicy,
- const comments::CommandTraits *Traits);
+ TextNodeDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors);
+ TextNodeDumper(raw_ostream &OS, bool ShowColors);
void Visit(const comments::Comment *C, const comments::FullComment *FC);
@@ -176,6 +189,8 @@ public:
void Visit(const GenericSelectionExpr::ConstAssociation &A);
+ void Visit(const APValue &Value, QualType Ty);
+
void dumpPointer(const void *Ptr);
void dumpLocation(SourceLocation Loc);
void dumpSourceRange(SourceRange R);
@@ -184,6 +199,7 @@ public:
void dumpBareDeclRef(const Decl *D);
void dumpName(const NamedDecl *ND);
void dumpAccessSpecifier(AccessSpecifier AS);
+ void dumpCleanupObject(const ExprWithCleanups::CleanupObject &C);
void dumpDeclRef(const Decl *D, StringRef Label = {});
@@ -230,6 +246,7 @@ public:
void VisitCaseStmt(const CaseStmt *Node);
void VisitConstantExpr(const ConstantExpr *Node);
void VisitCallExpr(const CallExpr *Node);
+ void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node);
void VisitCastExpr(const CastExpr *Node);
void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
void VisitDeclRefExpr(const DeclRefExpr *Node);
@@ -257,6 +274,9 @@ public:
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
void VisitCXXNewExpr(const CXXNewExpr *Node);
void VisitCXXDeleteExpr(const CXXDeleteExpr *Node);
+ void VisitTypeTraitExpr(const TypeTraitExpr *Node);
+ void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node);
+ void VisitExpressionTraitExpr(const ExpressionTraitExpr *Node);
void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
void VisitExprWithCleanups(const ExprWithCleanups *Node);
void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
@@ -273,6 +293,7 @@ public:
void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
+ void VisitOMPIteratorExpr(const OMPIteratorExpr *Node);
void VisitRValueReferenceType(const ReferenceType *T);
void VisitArrayType(const ArrayType *T);
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index f5955c45fafc..0fc50e0e799f 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -17,6 +17,7 @@
#ifndef LLVM_CLANG_AST_TYPE_H
#define LLVM_CLANG_AST_TYPE_H
+#include "clang/AST/DependenceFlags.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "clang/Basic/AddressSpaces.h"
@@ -44,8 +45,8 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
-#include "llvm/Support/type_traits.h"
#include "llvm/Support/TrailingObjects.h"
+#include "llvm/Support/type_traits.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -58,6 +59,7 @@ namespace clang {
class ExtQuals;
class QualType;
+class ConceptDecl;
class TagDecl;
class Type;
@@ -85,7 +87,7 @@ namespace llvm {
return static_cast< ::clang::Type*>(P);
}
- enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
+ static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits;
};
template<>
@@ -96,7 +98,7 @@ namespace llvm {
return static_cast< ::clang::ExtQuals*>(P);
}
- enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
+ static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits;
};
} // namespace llvm
@@ -942,6 +944,12 @@ public:
/// from non-class types (in C++) or all types (in C).
QualType getNonLValueExprType(const ASTContext &Context) const;
+ /// Remove an outer pack expansion type (if any) from this type. Used as part
+ /// of converting the type of a declaration to the type of an expression that
+ /// references that expression. It's meaningless for an expression to have a
+ /// pack expansion type.
+ QualType getNonPackExpansionType() const;
+
/// Return the specified type with any "sugar" removed from
/// the type. This takes off typedefs, typeof's etc. If the outer level of
/// the type is already concrete, it returns it unmodified. This is similar
@@ -1050,7 +1058,7 @@ public:
void dump(const char *s) const;
void dump() const;
- void dump(llvm::raw_ostream &OS) const;
+ void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
void Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddPointer(getAsOpaquePtr());
@@ -1062,6 +1070,21 @@ public:
/// Return the address space of this type.
inline LangAS getAddressSpace() const;
+ /// Returns true if address space qualifiers overlap with T address space
+ /// qualifiers.
+ /// OpenCL C defines conversion rules for pointers to different address spaces
+ /// and notion of overlapping address spaces.
+ /// CL1.1 or CL1.2:
+ /// address spaces overlap iff they are they same.
+ /// OpenCL C v2.0 s6.5.5 adds:
+ /// __generic overlaps with any address space except for __constant.
+ bool isAddressSpaceOverlapping(QualType T) const {
+ Qualifiers Q = getQualifiers();
+ Qualifiers TQ = T.getQualifiers();
+ // Address spaces overlap if at least one of them is a superset of another
+ return Q.isAddressSpaceSupersetOf(TQ) || TQ.isAddressSpaceSupersetOf(Q);
+ }
+
/// Returns gc attribute of this type.
inline Qualifiers::GC getObjCGCAttr() const;
@@ -1295,7 +1318,7 @@ struct PointerLikeTypeTraits<clang::QualType> {
}
// Various qualifiers go in low bits.
- enum { NumLowBitsAvailable = 0 };
+ static constexpr int NumLowBitsAvailable = 0;
};
} // namespace llvm
@@ -1464,19 +1487,8 @@ private:
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
unsigned TC : 8;
- /// Whether this type is a dependent type (C++ [temp.dep.type]).
- unsigned Dependent : 1;
-
- /// Whether this type somehow involves a template parameter, even
- /// if the resolution of the type does not depend on a template parameter.
- unsigned InstantiationDependent : 1;
-
- /// Whether this type is a variably-modified type (C99 6.7.5).
- unsigned VariablyModified : 1;
-
- /// Whether this type contains an unexpanded parameter pack
- /// (for C++11 variadic templates).
- unsigned ContainsUnexpandedParameterPack : 1;
+ /// Store information on the type dependency.
+ unsigned Dependence : llvm::BitWidth<TypeDependence>;
/// True if the cache (i.e. the bitfields here starting with
/// 'Cache') is valid.
@@ -1505,7 +1517,7 @@ private:
return CachedLocalOrUnnamed;
}
};
- enum { NumTypeBits = 18 };
+ enum { NumTypeBits = 8 + llvm::BitWidth<TypeDependence> + 6 };
protected:
// These classes allow subclasses to somewhat cleanly pack bitfields
@@ -1555,7 +1567,7 @@ protected:
/// Extra information which affects how the function is called, like
/// regparm and the calling convention.
- unsigned ExtInfo : 12;
+ unsigned ExtInfo : 13;
/// The ref-qualifier associated with a \c FunctionProtoType.
///
@@ -1659,11 +1671,21 @@ protected:
/// The kind of vector, either a generic vector type or some
/// target-specific vector type such as for AltiVec or Neon.
unsigned VecKind : 3;
-
/// The number of elements in the vector.
- unsigned NumElements : 29 - NumTypeBits;
+ uint32_t NumElements;
+ };
+
+ class ConstantMatrixTypeBitfields {
+ friend class ConstantMatrixType;
+
+ unsigned : NumTypeBits;
- enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 };
+ /// Number of rows and columns. Using 20 bits allows supporting very large
+ /// matrixes, while keeping 24 bits to accommodate NumTypeBits.
+ unsigned NumRows : 20;
+ unsigned NumColumns : 20;
+
+ static constexpr uint32_t MaxElementsPerDimension = (1 << 20) - 1;
};
class AttributedTypeBitfields {
@@ -1683,6 +1705,15 @@ protected:
/// Was this placeholder type spelled as 'auto', 'decltype(auto)',
/// or '__auto_type'? AutoTypeKeyword value.
unsigned Keyword : 2;
+
+ /// The number of template arguments in the type-constraints, which is
+ /// expected to be able to hold at least 1024 according to [implimits].
+ /// However as this limit is somewhat easy to hit with template
+ /// metaprogramming we'd prefer to keep it as large as possible.
+ /// At the moment it has been left as a non-bitfield since this type
+ /// safely fits in 64 bits as an unsigned, so there is no reason to
+ /// introduce the performance impact of a bitfield.
+ unsigned NumArgs;
};
class SubstTemplateTypeParmPackTypeBitfields {
@@ -1766,6 +1797,7 @@ protected:
TypeWithKeywordBitfields TypeWithKeywordBits;
ElaboratedTypeBitfields ElaboratedTypeBits;
VectorTypeBitfields VectorTypeBits;
+ ConstantMatrixTypeBitfields ConstantMatrixTypeBits;
SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
DependentTemplateSpecializationTypeBitfields
@@ -1818,16 +1850,11 @@ private:
protected:
friend class ASTContext;
- Type(TypeClass tc, QualType canon, bool Dependent,
- bool InstantiationDependent, bool VariablyModified,
- bool ContainsUnexpandedParameterPack)
+ Type(TypeClass tc, QualType canon, TypeDependence Dependence)
: ExtQualsTypeCommonBase(this,
canon.isNull() ? QualType(this_(), 0) : canon) {
TypeBits.TC = tc;
- TypeBits.Dependent = Dependent;
- TypeBits.InstantiationDependent = Dependent || InstantiationDependent;
- TypeBits.VariablyModified = VariablyModified;
- TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
+ TypeBits.Dependence = static_cast<unsigned>(Dependence);
TypeBits.CacheValid = false;
TypeBits.CachedLocalOrUnnamed = false;
TypeBits.CachedLinkage = NoLinkage;
@@ -1837,20 +1864,11 @@ protected:
// silence VC++ warning C4355: 'this' : used in base member initializer list
Type *this_() { return this; }
- void setDependent(bool D = true) {
- TypeBits.Dependent = D;
- if (D)
- TypeBits.InstantiationDependent = true;
+ void setDependence(TypeDependence D) {
+ TypeBits.Dependence = static_cast<unsigned>(D);
}
- void setInstantiationDependent(bool D = true) {
- TypeBits.InstantiationDependent = D; }
-
- void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; }
-
- void setContainsUnexpandedParameterPack(bool PP = true) {
- TypeBits.ContainsUnexpandedParameterPack = PP;
- }
+ void addDependence(TypeDependence D) { setDependence(getDependence() | D); }
public:
friend class ASTReader;
@@ -1884,7 +1902,7 @@ public:
///
/// Note that this routine does not specify which
bool containsUnexpandedParameterPack() const {
- return TypeBits.ContainsUnexpandedParameterPack;
+ return getDependence() & TypeDependence::UnexpandedPack;
}
/// Determines if this type would be canonical if it had no further
@@ -1898,6 +1916,15 @@ public:
/// or QualType::getSingleStepDesugaredType(const ASTContext&).
QualType getLocallyUnqualifiedSingleStepDesugaredType() const;
+ /// As an extension, we classify types as one of "sized" or "sizeless";
+ /// every type is one or the other. Standard types are all sized;
+ /// sizeless types are purely an extension.
+ ///
+ /// Sizeless types contain data with no specified size, alignment,
+ /// or layout.
+ bool isSizelessType() const;
+ bool isSizelessBuiltinType() const;
+
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.
@@ -1987,6 +2014,7 @@ public:
bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex)
bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half)
bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661
+ bool isBFloat16Type() const;
bool isFloat128Type() const;
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
@@ -2029,6 +2057,8 @@ public:
bool isComplexIntegerType() const; // GCC _Complex integer type.
bool isVectorType() const; // GCC vector type.
bool isExtVectorType() const; // Extended vector type.
+ bool isMatrixType() const; // Matrix type.
+ bool isConstantMatrixType() const; // Constant matrix type.
bool isDependentAddressSpaceType() const; // value-dependent address space qualifier
bool isObjCObjectPointerType() const; // pointer to ObjC object
bool isObjCRetainableType() const; // ObjC object or block pointer
@@ -2109,6 +2139,7 @@ public:
bool isOCLExtOpaqueType() const; // Any OpenCL extension type
bool isPipeType() const; // OpenCL pipe type
+ bool isExtIntType() const; // Extended Int Type
bool isOpenCLSpecificType() const; // Any OpenCL specific type
/// Determines if this type, which must satisfy
@@ -2116,6 +2147,11 @@ public:
/// than implicitly __strong.
bool isObjCARCImplicitlyUnretainedType() const;
+ /// Check if the type is the CUDA device builtin surface type.
+ bool isCUDADeviceBuiltinSurfaceType() const;
+ /// Check if the type is the CUDA device builtin texture type.
+ bool isCUDADeviceBuiltinTextureType() const;
+
/// Return the implicit lifetime for this type, which must not be dependent.
Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const;
@@ -2135,16 +2171,27 @@ public:
/// Given that this is a scalar type, classify it.
ScalarTypeKind getScalarTypeKind() const;
+ TypeDependence getDependence() const {
+ return static_cast<TypeDependence>(TypeBits.Dependence);
+ }
+
+ /// Whether this type is an error type.
+ bool containsErrors() const {
+ return getDependence() & TypeDependence::Error;
+ }
+
/// Whether this type is a dependent type, meaning that its definition
/// somehow depends on a template parameter (C++ [temp.dep.type]).
- bool isDependentType() const { return TypeBits.Dependent; }
+ bool isDependentType() const {
+ return getDependence() & TypeDependence::Dependent;
+ }
/// Determine whether this type is an instantiation-dependent type,
/// meaning that the type involves a template parameter (even if the
/// definition does not actually depend on the type substituted for that
/// template parameter).
bool isInstantiationDependentType() const {
- return TypeBits.InstantiationDependent;
+ return getDependence() & TypeDependence::Instantiation;
}
/// Determine whether this type is an undeduced type, meaning that
@@ -2153,7 +2200,9 @@ public:
bool isUndeducedType() const;
/// Whether this type is a variably-modified type (C99 6.7.5).
- bool isVariablyModifiedType() const { return TypeBits.VariablyModified; }
+ bool isVariablyModifiedType() const {
+ return getDependence() & TypeDependence::VariablyModified;
+ }
/// Whether this type involves a variable-length array type
/// with a definite size.
@@ -2422,7 +2471,7 @@ public:
CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
void dump() const;
- void dump(llvm::raw_ostream &OS) const;
+ void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
};
/// This will check for a TypedefType by removing any existing sugar
@@ -2474,10 +2523,9 @@ private:
friend class ASTContext; // ASTContext creates these.
BuiltinType(Kind K)
- : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
- /*InstantiationDependent=*/(K == Dependent),
- /*VariablyModified=*/false,
- /*Unexpanded parameter pack=*/false) {
+ : Type(Builtin, QualType(),
+ K == Dependent ? TypeDependence::DependentInstantiation
+ : TypeDependence::None) {
BuiltinTypeBits.Kind = K;
}
@@ -2547,10 +2595,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode {
QualType ElementType;
ComplexType(QualType Element, QualType CanonicalPtr)
- : Type(Complex, CanonicalPtr, Element->isDependentType(),
- Element->isInstantiationDependentType(),
- Element->isVariablyModifiedType(),
- Element->containsUnexpandedParameterPack()),
+ : Type(Complex, CanonicalPtr, Element->getDependence()),
ElementType(Element) {}
public:
@@ -2577,11 +2622,7 @@ class ParenType : public Type, public llvm::FoldingSetNode {
QualType Inner;
ParenType(QualType InnerType, QualType CanonType)
- : Type(Paren, CanonType, InnerType->isDependentType(),
- InnerType->isInstantiationDependentType(),
- InnerType->isVariablyModifiedType(),
- InnerType->containsUnexpandedParameterPack()),
- Inner(InnerType) {}
+ : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {}
public:
QualType getInnerType() const { return Inner; }
@@ -2607,31 +2648,12 @@ class PointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
PointerType(QualType Pointee, QualType CanonicalPtr)
- : Type(Pointer, CanonicalPtr, Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
+ : Type(Pointer, CanonicalPtr, Pointee->getDependence()),
PointeeType(Pointee) {}
public:
QualType getPointeeType() const { return PointeeType; }
- /// Returns true if address spaces of pointers overlap.
- /// OpenCL v2.0 defines conversion rules for pointers to different
- /// address spaces (OpenCLC v2.0 s6.5.5) and notion of overlapping
- /// address spaces.
- /// CL1.1 or CL1.2:
- /// address spaces overlap iff they are they same.
- /// CL2.0 adds:
- /// __generic overlaps with any address space except for __constant.
- bool isAddressSpaceOverlapping(const PointerType &other) const {
- Qualifiers thisQuals = PointeeType.getQualifiers();
- Qualifiers otherQuals = other.getPointeeType().getQualifiers();
- // Address spaces overlap if at least one of them is a superset of another
- return thisQuals.isAddressSpaceSupersetOf(otherQuals) ||
- otherQuals.isAddressSpaceSupersetOf(thisQuals);
- }
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2658,10 +2680,7 @@ protected:
AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
QualType CanonicalPtr)
- : Type(TC, CanonicalPtr, OriginalTy->isDependentType(),
- OriginalTy->isInstantiationDependentType(),
- OriginalTy->isVariablyModifiedType(),
- OriginalTy->containsUnexpandedParameterPack()),
+ : Type(TC, CanonicalPtr, OriginalTy->getDependence()),
OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
public:
@@ -2710,10 +2729,7 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
BlockPointerType(QualType Pointee, QualType CanonicalCls)
- : Type(BlockPointer, CanonicalCls, Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
+ : Type(BlockPointer, CanonicalCls, Pointee->getDependence()),
PointeeType(Pointee) {}
public:
@@ -2743,10 +2759,7 @@ class ReferenceType : public Type, public llvm::FoldingSetNode {
protected:
ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
bool SpelledAsLValue)
- : Type(tc, CanonicalRef, Referencee->isDependentType(),
- Referencee->isInstantiationDependentType(),
- Referencee->isVariablyModifiedType(),
- Referencee->containsUnexpandedParameterPack()),
+ : Type(tc, CanonicalRef, Referencee->getDependence()),
PointeeType(Referencee) {
ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue;
ReferenceTypeBits.InnerRef = Referencee->isReferenceType();
@@ -2831,13 +2844,9 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr)
: Type(MemberPointer, CanonicalPtr,
- Cls->isDependentType() || Pointee->isDependentType(),
- (Cls->isInstantiationDependentType() ||
- Pointee->isInstantiationDependentType()),
- Pointee->isVariablyModifiedType(),
- (Cls->containsUnexpandedParameterPack() ||
- Pointee->containsUnexpandedParameterPack())),
- PointeeType(Pointee), Class(Cls) {}
+ (Cls->getDependence() & ~TypeDependence::VariablyModified) |
+ Pointee->getDependence()),
+ PointeeType(Pointee), Class(Cls) {}
public:
QualType getPointeeType() const { return PointeeType; }
@@ -3260,10 +3269,6 @@ public:
QualType getElementType() const { return ElementType; }
unsigned getNumElements() const { return VectorTypeBits.NumElements; }
- static bool isVectorSizeTooLarge(unsigned NumElements) {
- return NumElements > VectorTypeBitfields::MaxNumElements;
- }
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -3407,6 +3412,136 @@ public:
}
};
+/// Represents a matrix type, as defined in the Matrix Types clang extensions.
+/// __attribute__((matrix_type(rows, columns))), where "rows" specifies
+/// number of rows and "columns" specifies the number of columns.
+class MatrixType : public Type, public llvm::FoldingSetNode {
+protected:
+ friend class ASTContext;
+
+ /// The element type of the matrix.
+ QualType ElementType;
+
+ MatrixType(QualType ElementTy, QualType CanonElementTy);
+
+ MatrixType(TypeClass TypeClass, QualType ElementTy, QualType CanonElementTy,
+ const Expr *RowExpr = nullptr, const Expr *ColumnExpr = nullptr);
+
+public:
+ /// Returns type of the elements being stored in the matrix
+ QualType getElementType() const { return ElementType; }
+
+ /// Valid elements types are the following:
+ /// * an integer type (as in C2x 6.2.5p19), but excluding enumerated types
+ /// and _Bool
+ /// * the standard floating types float or double
+ /// * a half-precision floating point type, if one is supported on the target
+ static bool isValidElementType(QualType T) {
+ return T->isDependentType() ||
+ (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType());
+ }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == ConstantMatrix ||
+ T->getTypeClass() == DependentSizedMatrix;
+ }
+};
+
+/// Represents a concrete matrix type with constant number of rows and columns
+class ConstantMatrixType final : public MatrixType {
+protected:
+ friend class ASTContext;
+
+ /// The element type of the matrix.
+ QualType ElementType;
+
+ ConstantMatrixType(QualType MatrixElementType, unsigned NRows,
+ unsigned NColumns, QualType CanonElementType);
+
+ ConstantMatrixType(TypeClass typeClass, QualType MatrixType, unsigned NRows,
+ unsigned NColumns, QualType CanonElementType);
+
+public:
+ /// Returns the number of rows in the matrix.
+ unsigned getNumRows() const { return ConstantMatrixTypeBits.NumRows; }
+
+ /// Returns the number of columns in the matrix.
+ unsigned getNumColumns() const { return ConstantMatrixTypeBits.NumColumns; }
+
+ /// Returns the number of elements required to embed the matrix into a vector.
+ unsigned getNumElementsFlattened() const {
+ return ConstantMatrixTypeBits.NumRows * ConstantMatrixTypeBits.NumColumns;
+ }
+
+ /// Returns true if \p NumElements is a valid matrix dimension.
+ static bool isDimensionValid(uint64_t NumElements) {
+ return NumElements > 0 &&
+ NumElements <= ConstantMatrixTypeBitfields::MaxElementsPerDimension;
+ }
+
+ /// Returns the maximum number of elements per dimension.
+ static unsigned getMaxElementsPerDimension() {
+ return ConstantMatrixTypeBitfields::MaxElementsPerDimension;
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getElementType(), getNumRows(), getNumColumns(),
+ getTypeClass());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
+ unsigned NumRows, unsigned NumColumns,
+ TypeClass TypeClass) {
+ ID.AddPointer(ElementType.getAsOpaquePtr());
+ ID.AddInteger(NumRows);
+ ID.AddInteger(NumColumns);
+ ID.AddInteger(TypeClass);
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == ConstantMatrix;
+ }
+};
+
+/// Represents a matrix type where the type and the number of rows and columns
+/// is dependent on a template.
+class DependentSizedMatrixType final : public MatrixType {
+ friend class ASTContext;
+
+ const ASTContext &Context;
+ Expr *RowExpr;
+ Expr *ColumnExpr;
+
+ SourceLocation loc;
+
+ DependentSizedMatrixType(const ASTContext &Context, QualType ElementType,
+ QualType CanonicalType, Expr *RowExpr,
+ Expr *ColumnExpr, SourceLocation loc);
+
+public:
+ QualType getElementType() const { return ElementType; }
+ Expr *getRowExpr() const { return RowExpr; }
+ Expr *getColumnExpr() const { return ColumnExpr; }
+ SourceLocation getAttributeLoc() const { return loc; }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == DependentSizedMatrix;
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+ QualType ElementType, Expr *RowExpr, Expr *ColumnExpr);
+};
+
/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
/// class of FunctionNoProtoType and FunctionProtoType.
class FunctionType : public Type {
@@ -3523,39 +3658,41 @@ public:
class ExtInfo {
friend class FunctionType;
- // Feel free to rearrange or add bits, but if you go over 12,
- // you'll need to adjust both the Bits field below and
- // Type::FunctionTypeBitfields.
+ // Feel free to rearrange or add bits, but if you go over 16, you'll need to
+ // adjust the Bits field below, and if you add bits, you'll need to adjust
+ // Type::FunctionTypeBitfields::ExtInfo as well.
- // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|
- // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 |
+ // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|cmsenscall|
+ // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 | 12 |
//
// regparm is either 0 (no regparm attribute) or the regparm value+1.
enum { CallConvMask = 0x1F };
enum { NoReturnMask = 0x20 };
enum { ProducesResultMask = 0x40 };
enum { NoCallerSavedRegsMask = 0x80 };
- enum { NoCfCheckMask = 0x800 };
enum {
- RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask |
- NoCallerSavedRegsMask | NoCfCheckMask),
+ RegParmMask = 0x700,
RegParmOffset = 8
- }; // Assumed to be the last field
+ };
+ enum { NoCfCheckMask = 0x800 };
+ enum { CmseNSCallMask = 0x1000 };
uint16_t Bits = CC_C;
ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
- public:
- // Constructor with no defaults. Use this when you know that you
- // have all the elements (when reading an AST file for example).
- ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
- bool producesResult, bool noCallerSavedRegs, bool NoCfCheck) {
- assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
- Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) |
- (producesResult ? ProducesResultMask : 0) |
- (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) |
- (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) |
- (NoCfCheck ? NoCfCheckMask : 0);
+ public:
+ // Constructor with no defaults. Use this when you know that you
+ // have all the elements (when reading an AST file for example).
+ ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
+ bool producesResult, bool noCallerSavedRegs, bool NoCfCheck,
+ bool cmseNSCall) {
+ assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
+ Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) |
+ (producesResult ? ProducesResultMask : 0) |
+ (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) |
+ (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) |
+ (NoCfCheck ? NoCfCheckMask : 0) |
+ (cmseNSCall ? CmseNSCallMask : 0);
}
// Constructor with all defaults. Use when for example creating a
@@ -3568,9 +3705,10 @@ public:
bool getNoReturn() const { return Bits & NoReturnMask; }
bool getProducesResult() const { return Bits & ProducesResultMask; }
+ bool getCmseNSCall() const { return Bits & CmseNSCallMask; }
bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; }
bool getNoCfCheck() const { return Bits & NoCfCheckMask; }
- bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; }
+ bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; }
unsigned getRegParm() const {
unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset;
@@ -3605,6 +3743,13 @@ public:
return ExtInfo(Bits & ~ProducesResultMask);
}
+ ExtInfo withCmseNSCall(bool cmseNSCall) const {
+ if (cmseNSCall)
+ return ExtInfo(Bits | CmseNSCallMask);
+ else
+ return ExtInfo(Bits & ~CmseNSCallMask);
+ }
+
ExtInfo withNoCallerSavedRegs(bool noCallerSavedRegs) const {
if (noCallerSavedRegs)
return ExtInfo(Bits | NoCallerSavedRegsMask);
@@ -3651,14 +3796,9 @@ public:
};
protected:
- FunctionType(TypeClass tc, QualType res,
- QualType Canonical, bool Dependent,
- bool InstantiationDependent,
- bool VariablyModified, bool ContainsUnexpandedParameterPack,
- ExtInfo Info)
- : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
- ContainsUnexpandedParameterPack),
- ResultType(res) {
+ FunctionType(TypeClass tc, QualType res, QualType Canonical,
+ TypeDependence Dependence, ExtInfo Info)
+ : Type(tc, Canonical, Dependence), ResultType(res) {
FunctionTypeBits.ExtInfo = Info.Bits;
}
@@ -3677,6 +3817,7 @@ public:
/// type.
bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
+ bool getCmseNSCallAttr() const { return getExtInfo().getCmseNSCall(); }
CallingConv getCallConv() const { return getExtInfo().getCC(); }
ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
@@ -3709,9 +3850,10 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
: FunctionType(FunctionNoProto, Result, Canonical,
- /*Dependent=*/false, /*InstantiationDependent=*/false,
- Result->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false, Info) {}
+ Result->getDependence() &
+ ~(TypeDependence::DependentInstantiation |
+ TypeDependence::UnexpandedPack),
+ Info) {}
public:
// No additional state past what FunctionType provides.
@@ -4203,9 +4345,9 @@ class UnresolvedUsingType : public Type {
UnresolvedUsingTypenameDecl *Decl;
UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
- : Type(UnresolvedUsing, QualType(), true, true, false,
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
+ : Type(UnresolvedUsing, QualType(),
+ TypeDependence::DependentInstantiation),
+ Decl(const_cast<UnresolvedUsingTypenameDecl *>(D)) {}
public:
UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
@@ -4234,11 +4376,8 @@ protected:
friend class ASTContext; // ASTContext creates these.
TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
- : Type(tc, can, can->isDependentType(),
- can->isInstantiationDependentType(),
- can->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(const_cast<TypedefNameDecl*>(D)) {
+ : Type(tc, can, can->getDependence() & ~TypeDependence::UnexpandedPack),
+ Decl(const_cast<TypedefNameDecl *>(D)) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
@@ -4261,10 +4400,7 @@ class MacroQualifiedType : public Type {
MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy,
const IdentifierInfo *MacroII)
- : Type(MacroQualified, CanonTy, UnderlyingTy->isDependentType(),
- UnderlyingTy->isInstantiationDependentType(),
- UnderlyingTy->isVariablyModifiedType(),
- UnderlyingTy->containsUnexpandedParameterPack()),
+ : Type(MacroQualified, CanonTy, UnderlyingTy->getDependence()),
UnderlyingTy(UnderlyingTy), MacroII(MacroII) {
assert(isa<AttributedType>(UnderlyingTy) &&
"Expected a macro qualified type to only wrap attributed types.");
@@ -4336,11 +4472,7 @@ class TypeOfType : public Type {
QualType TOType;
TypeOfType(QualType T, QualType can)
- : Type(TypeOf, can, T->isDependentType(),
- T->isInstantiationDependentType(),
- T->isVariablyModifiedType(),
- T->containsUnexpandedParameterPack()),
- TOType(T) {
+ : Type(TypeOf, can, T->getDependence()), TOType(T) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
@@ -4549,10 +4681,7 @@ private:
AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
QualType equivalent)
- : Type(Attributed, canon, equivalent->isDependentType(),
- equivalent->isInstantiationDependentType(),
- equivalent->isVariablyModifiedType(),
- equivalent->containsUnexpandedParameterPack()),
+ : Type(Attributed, canon, equivalent->getDependence()),
ModifiedType(modified), EquivalentType(equivalent) {
AttributedTypeBits.AttrKind = attrKind;
}
@@ -4654,18 +4783,16 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
/// Build a non-canonical type.
TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
- : Type(TemplateTypeParm, Canon, /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- Canon->containsUnexpandedParameterPack()),
+ : Type(TemplateTypeParm, Canon,
+ TypeDependence::DependentInstantiation |
+ (Canon->getDependence() & TypeDependence::UnexpandedPack)),
TTPDecl(TTPDecl) {}
/// Build the canonical type.
TemplateTypeParmType(unsigned D, unsigned I, bool PP)
: Type(TemplateTypeParm, QualType(this, 0),
- /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false, PP) {
+ TypeDependence::DependentInstantiation |
+ (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)) {
CanTTPTInfo.Depth = D;
CanTTPTInfo.Index = I;
CanTTPTInfo.ParameterPack = PP;
@@ -4722,10 +4849,7 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
const TemplateTypeParmType *Replaced;
SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
- : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(),
- Canon->isInstantiationDependentType(),
- Canon->isVariablyModifiedType(),
- Canon->containsUnexpandedParameterPack()),
+ : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()),
Replaced(Param) {}
public:
@@ -4814,8 +4938,7 @@ public:
/// Common base class for placeholders for types that get replaced by
/// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced
-/// class template types, and (eventually) constrained type names from the C++
-/// Concepts TS.
+/// class template types, and constrained type names.
///
/// These types are usually a placeholder for a deduced type. However, before
/// the initializer is attached, or (usually) if the initializer is
@@ -4823,23 +4946,16 @@ public:
/// the latter case, it is also a dependent type.
class DeducedType : public Type {
protected:
- DeducedType(TypeClass TC, QualType DeducedAsType, bool IsDependent,
- bool IsInstantiationDependent, bool ContainsParameterPack)
+ DeducedType(TypeClass TC, QualType DeducedAsType,
+ TypeDependence ExtraDependence)
: Type(TC,
// FIXME: Retain the sugared deduced type?
DeducedAsType.isNull() ? QualType(this, 0)
: DeducedAsType.getCanonicalType(),
- IsDependent, IsInstantiationDependent,
- /*VariablyModified=*/false, ContainsParameterPack) {
- if (!DeducedAsType.isNull()) {
- if (DeducedAsType->isDependentType())
- setDependent();
- if (DeducedAsType->isInstantiationDependentType())
- setInstantiationDependent();
- if (DeducedAsType->containsUnexpandedParameterPack())
- setContainsUnexpandedParameterPack();
- }
- }
+ ExtraDependence | (DeducedAsType.isNull()
+ ? TypeDependence::None
+ : DeducedAsType->getDependence() &
+ ~TypeDependence::VariablyModified)) {}
public:
bool isSugared() const { return !isCanonicalUnqualified(); }
@@ -4860,18 +4976,50 @@ public:
}
};
-/// Represents a C++11 auto or C++14 decltype(auto) type.
-class AutoType : public DeducedType, public llvm::FoldingSetNode {
+/// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained
+/// by a type-constraint.
+class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
+ ConceptDecl *TypeConstraintConcept;
+
AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
- bool IsDeducedAsDependent, bool IsDeducedAsPack)
- : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent,
- IsDeducedAsDependent, IsDeducedAsPack) {
- AutoTypeBits.Keyword = (unsigned)Keyword;
+ TypeDependence ExtraDependence, ConceptDecl *CD,
+ ArrayRef<TemplateArgument> TypeConstraintArgs);
+
+ const TemplateArgument *getArgBuffer() const {
+ return reinterpret_cast<const TemplateArgument*>(this+1);
+ }
+
+ TemplateArgument *getArgBuffer() {
+ return reinterpret_cast<TemplateArgument*>(this+1);
}
public:
+ /// Retrieve the template arguments.
+ const TemplateArgument *getArgs() const {
+ return getArgBuffer();
+ }
+
+ /// Retrieve the number of template arguments.
+ unsigned getNumArgs() const {
+ return AutoTypeBits.NumArgs;
+ }
+
+ const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
+
+ ArrayRef<TemplateArgument> getTypeConstraintArguments() const {
+ return {getArgs(), getNumArgs()};
+ }
+
+ ConceptDecl *getTypeConstraintConcept() const {
+ return TypeConstraintConcept;
+ }
+
+ bool isConstrained() const {
+ return TypeConstraintConcept != nullptr;
+ }
+
bool isDecltypeAuto() const {
return getKeyword() == AutoTypeKeyword::DecltypeAuto;
}
@@ -4880,18 +5028,15 @@ public:
return (AutoTypeKeyword)AutoTypeBits.Keyword;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getDeducedType(), getKeyword(), isDependentType(),
- containsUnexpandedParameterPack());
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
+ Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
+ getTypeConstraintConcept(), getTypeConstraintArguments());
}
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced,
- AutoTypeKeyword Keyword, bool IsDependent, bool IsPack) {
- ID.AddPointer(Deduced.getAsOpaquePtr());
- ID.AddInteger((unsigned)Keyword);
- ID.AddBoolean(IsDependent);
- ID.AddBoolean(IsPack);
- }
+ static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+ QualType Deduced, AutoTypeKeyword Keyword,
+ bool IsDependent, ConceptDecl *CD,
+ ArrayRef<TemplateArgument> Arguments);
static bool classof(const Type *T) {
return T->getTypeClass() == Auto;
@@ -4910,9 +5055,10 @@ class DeducedTemplateSpecializationType : public DeducedType,
QualType DeducedAsType,
bool IsDeducedAsDependent)
: DeducedType(DeducedTemplateSpecialization, DeducedAsType,
- IsDeducedAsDependent || Template.isDependent(),
- IsDeducedAsDependent || Template.isInstantiationDependent(),
- Template.containsUnexpandedParameterPack()),
+ toTypeDependence(Template.getDependence()) |
+ (IsDeducedAsDependent
+ ? TypeDependence::DependentInstantiation
+ : TypeDependence::None)),
Template(Template) {}
public:
@@ -5114,10 +5260,8 @@ class InjectedClassNameType : public Type {
QualType InjectedType;
InjectedClassNameType(CXXRecordDecl *D, QualType TST)
- : Type(InjectedClassName, QualType(), /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- /*ContainsUnexpandedParameterPack=*/false),
+ : Type(InjectedClassName, QualType(),
+ TypeDependence::DependentInstantiation),
Decl(D), InjectedType(TST) {
assert(isa<TemplateSpecializationType>(TST));
assert(!TST.hasQualifiers());
@@ -5196,11 +5340,8 @@ enum ElaboratedTypeKeyword {
class TypeWithKeyword : public Type {
protected:
TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
- QualType Canonical, bool Dependent,
- bool InstantiationDependent, bool VariablyModified,
- bool ContainsUnexpandedParameterPack)
- : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
- ContainsUnexpandedParameterPack) {
+ QualType Canonical, TypeDependence Dependence)
+ : Type(tc, Canonical, Dependence) {
TypeWithKeywordBits.Keyword = Keyword;
}
@@ -5264,10 +5405,7 @@ class ElaboratedType final
ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl)
: TypeWithKeyword(Keyword, Elaborated, CanonType,
- NamedType->isDependentType(),
- NamedType->isInstantiationDependentType(),
- NamedType->isVariablyModifiedType(),
- NamedType->containsUnexpandedParameterPack()),
+ NamedType->getDependence()),
NNS(NNS), NamedType(NamedType) {
ElaboratedTypeBits.HasOwnedTagDecl = false;
if (OwnedTagDecl) {
@@ -5338,10 +5476,9 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, QualType CanonType)
- : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- NNS->containsUnexpandedParameterPack()),
+ : TypeWithKeyword(Keyword, DependentName, CanonType,
+ TypeDependence::DependentInstantiation |
+ toTypeDependence(NNS->getDependence())),
NNS(NNS), Name(Name) {}
public:
@@ -5478,10 +5615,9 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
PackExpansionType(QualType Pattern, QualType Canon,
Optional<unsigned> NumExpansions)
- : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/Pattern->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false),
+ : Type(PackExpansion, Canon,
+ (Pattern->getDependence() | TypeDependence::Instantiation) &
+ ~TypeDependence::UnexpandedPack),
Pattern(Pattern) {
PackExpansionTypeBits.NumExpansions =
NumExpansions ? *NumExpansions + 1 : 0;
@@ -5620,6 +5756,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID,
const ObjCTypeParamDecl *OTPDecl,
+ QualType CanonicalType,
ArrayRef<ObjCProtocolDecl *> protocols);
ObjCTypeParamDecl *getDecl() const { return OTPDecl; }
@@ -5700,8 +5837,8 @@ protected:
bool isKindOf);
ObjCObjectType(enum Nonce_ObjCInterface)
- : Type(ObjCInterface, QualType(), false, false, false, false),
- BaseType(QualType(this_(), 0)) {
+ : Type(ObjCInterface, QualType(), TypeDependence::None),
+ BaseType(QualType(this_(), 0)) {
ObjCObjectTypeBits.NumProtocols = 0;
ObjCObjectTypeBits.NumTypeArgs = 0;
ObjCObjectTypeBits.IsKindOf = 0;
@@ -5916,11 +6053,7 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
ObjCObjectPointerType(QualType Canonical, QualType Pointee)
- : Type(ObjCObjectPointer, Canonical,
- Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
+ : Type(ObjCObjectPointer, Canonical, Pointee->getDependence()),
PointeeType(Pointee) {}
public:
@@ -6090,11 +6223,7 @@ class AtomicType : public Type, public llvm::FoldingSetNode {
QualType ValueType;
AtomicType(QualType ValTy, QualType Canonical)
- : Type(Atomic, Canonical, ValTy->isDependentType(),
- ValTy->isInstantiationDependentType(),
- ValTy->isVariablyModifiedType(),
- ValTy->containsUnexpandedParameterPack()),
- ValueType(ValTy) {}
+ : Type(Atomic, Canonical, ValTy->getDependence()), ValueType(ValTy) {}
public:
/// Gets the type contained by this atomic type, i.e.
@@ -6125,10 +6254,7 @@ class PipeType : public Type, public llvm::FoldingSetNode {
bool isRead;
PipeType(QualType elemType, QualType CanonicalPtr, bool isRead)
- : Type(Pipe, CanonicalPtr, elemType->isDependentType(),
- elemType->isInstantiationDependentType(),
- elemType->isVariablyModifiedType(),
- elemType->containsUnexpandedParameterPack()),
+ : Type(Pipe, CanonicalPtr, elemType->getDependence()),
ElementType(elemType), isRead(isRead) {}
public:
@@ -6154,6 +6280,64 @@ public:
bool isReadOnly() const { return isRead; }
};
+/// A fixed int type of a specified bitwidth.
+class ExtIntType final : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext;
+ unsigned IsUnsigned : 1;
+ unsigned NumBits : 24;
+
+protected:
+ ExtIntType(bool isUnsigned, unsigned NumBits);
+
+public:
+ bool isUnsigned() const { return IsUnsigned; }
+ bool isSigned() const { return !IsUnsigned; }
+ unsigned getNumBits() const { return NumBits; }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, isUnsigned(), getNumBits());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, bool IsUnsigned,
+ unsigned NumBits) {
+ ID.AddBoolean(IsUnsigned);
+ ID.AddInteger(NumBits);
+ }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == ExtInt; }
+};
+
+class DependentExtIntType final : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext;
+ const ASTContext &Context;
+ llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned;
+
+protected:
+ DependentExtIntType(const ASTContext &Context, bool IsUnsigned,
+ Expr *NumBits);
+
+public:
+ bool isUnsigned() const;
+ bool isSigned() const { return !isUnsigned(); }
+ Expr *getNumBitsExpr() const;
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Context, isUnsigned(), getNumBitsExpr());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+ bool IsUnsigned, Expr *NumBitsExpr);
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == DependentExtInt;
+ }
+};
+
/// A qualifier set is used to build a set of qualifiers.
class QualifierCollector : public Qualifiers {
public:
@@ -6573,6 +6757,14 @@ inline bool Type::isExtVectorType() const {
return isa<ExtVectorType>(CanonicalType);
}
+inline bool Type::isMatrixType() const {
+ return isa<MatrixType>(CanonicalType);
+}
+
+inline bool Type::isConstantMatrixType() const {
+ return isa<ConstantMatrixType>(CanonicalType);
+}
+
inline bool Type::isDependentAddressSpaceType() const {
return isa<DependentAddressSpaceType>(CanonicalType);
}
@@ -6673,6 +6865,10 @@ inline bool Type::isPipeType() const {
return isa<PipeType>(CanonicalType);
}
+inline bool Type::isExtIntType() const {
+ return isa<ExtIntType>(CanonicalType);
+}
+
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
inline bool Type::is##Id##Type() const { \
return isSpecificBuiltinType(BuiltinType::Id); \
@@ -6704,9 +6900,9 @@ inline bool Type::isTemplateTypeParmType() const {
}
inline bool Type::isSpecificBuiltinType(unsigned K) const {
- if (const BuiltinType *BT = getAs<BuiltinType>())
- if (BT->getKind() == (BuiltinType::Kind) K)
- return true;
+ if (const BuiltinType *BT = getAs<BuiltinType>()) {
+ return BT->getKind() == static_cast<BuiltinType::Kind>(K);
+ }
return false;
}
@@ -6725,9 +6921,7 @@ inline const BuiltinType *Type::getAsPlaceholderType() const {
inline bool Type::isSpecificPlaceholderType(unsigned K) const {
assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K));
- if (const auto *BT = dyn_cast<BuiltinType>(this))
- return (BT->getKind() == (BuiltinType::Kind) K);
- return false;
+ return isSpecificBuiltinType(K);
}
inline bool Type::isNonOverloadPlaceholderType() const {
@@ -6737,34 +6931,28 @@ inline bool Type::isNonOverloadPlaceholderType() const {
}
inline bool Type::isVoidType() const {
- if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Void;
- return false;
+ return isSpecificBuiltinType(BuiltinType::Void);
}
inline bool Type::isHalfType() const {
- if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Half;
// FIXME: Should we allow complex __fp16? Probably not.
- return false;
+ return isSpecificBuiltinType(BuiltinType::Half);
}
inline bool Type::isFloat16Type() const {
- if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Float16;
- return false;
+ return isSpecificBuiltinType(BuiltinType::Float16);
+}
+
+inline bool Type::isBFloat16Type() const {
+ return isSpecificBuiltinType(BuiltinType::BFloat16);
}
inline bool Type::isFloat128Type() const {
- if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Float128;
- return false;
+ return isSpecificBuiltinType(BuiltinType::Float128);
}
inline bool Type::isNullPtrType() const {
- if (const auto *BT = getAs<BuiltinType>())
- return BT->getKind() == BuiltinType::NullPtr;
- return false;
+ return isSpecificBuiltinType(BuiltinType::NullPtr);
}
bool IsEnumDeclComplete(EnumDecl *);
@@ -6780,7 +6968,7 @@ inline bool Type::isIntegerType() const {
return IsEnumDeclComplete(ET->getDecl()) &&
!IsEnumDeclScoped(ET->getDecl());
}
- return false;
+ return isExtIntType();
}
inline bool Type::isFixedPointType() const {
@@ -6837,7 +7025,8 @@ inline bool Type::isScalarType() const {
isa<BlockPointerType>(CanonicalType) ||
isa<MemberPointerType>(CanonicalType) ||
isa<ComplexType>(CanonicalType) ||
- isa<ObjCObjectPointerType>(CanonicalType);
+ isa<ObjCObjectPointerType>(CanonicalType) ||
+ isExtIntType();
}
inline bool Type::isIntegralOrEnumerationType() const {
@@ -6850,7 +7039,7 @@ inline bool Type::isIntegralOrEnumerationType() const {
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
return IsEnumDeclComplete(ET->getDecl());
- return false;
+ return isExtIntType();
}
inline bool Type::isBooleanType() const {
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index c3baaa3e4174..72cc8ef098e7 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_TYPELOC_H
#define LLVM_CLANG_AST_TYPELOC_H
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
@@ -34,6 +35,7 @@ namespace clang {
class Attr;
class ASTContext;
class CXXRecordDecl;
+class ConceptDecl;
class Expr;
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
@@ -181,6 +183,11 @@ public:
/// AttributedTypeLoc, for those type attributes that behave as qualifiers
TypeLoc findExplicitQualifierLoc() const;
+ /// Get the typeloc of an AutoType whose type will be deduced for a variable
+ /// with an initializer of this type. This looks through declarators like
+ /// pointer types, but not through decltype or typedefs.
+ AutoTypeLoc getContainedAutoTypeLoc() const;
+
/// Initializes this to state that every location in this
/// type is the given location.
///
@@ -1728,6 +1735,7 @@ public:
void initializeLocal(ASTContext &Context, SourceLocation loc) {
setAttrNameLoc(loc);
+ setAttrOperandParensRange(loc);
setAttrOperandParensRange(SourceRange(loc));
setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
}
@@ -1767,6 +1775,68 @@ class DependentSizedExtVectorTypeLoc :
DependentSizedExtVectorType> {
};
+struct MatrixTypeLocInfo {
+ SourceLocation AttrLoc;
+ SourceRange OperandParens;
+ Expr *RowOperand;
+ Expr *ColumnOperand;
+};
+
+class MatrixTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, MatrixTypeLoc,
+ MatrixType, MatrixTypeLocInfo> {
+public:
+ /// The location of the attribute name, i.e.
+ /// float __attribute__((matrix_type(4, 2)))
+ /// ^~~~~~~~~~~~~~~~~
+ SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; }
+ void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; }
+
+ /// The attribute's row operand, if it has one.
+ /// float __attribute__((matrix_type(4, 2)))
+ /// ^
+ Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; }
+ void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; }
+
+ /// The attribute's column operand, if it has one.
+ /// float __attribute__((matrix_type(4, 2)))
+ /// ^
+ Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; }
+ void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; }
+
+ /// The location of the parentheses around the operand, if there is
+ /// an operand.
+ /// float __attribute__((matrix_type(4, 2)))
+ /// ^ ^
+ SourceRange getAttrOperandParensRange() const {
+ return getLocalData()->OperandParens;
+ }
+ void setAttrOperandParensRange(SourceRange range) {
+ getLocalData()->OperandParens = range;
+ }
+
+ SourceRange getLocalSourceRange() const {
+ SourceRange range(getAttrNameLoc());
+ range.setEnd(getAttrOperandParensRange().getEnd());
+ return range;
+ }
+
+ void initializeLocal(ASTContext &Context, SourceLocation loc) {
+ setAttrNameLoc(loc);
+ setAttrOperandParensRange(loc);
+ setAttrRowOperand(nullptr);
+ setAttrColumnOperand(nullptr);
+ }
+};
+
+class ConstantMatrixTypeLoc
+ : public InheritingConcreteTypeLoc<MatrixTypeLoc, ConstantMatrixTypeLoc,
+ ConstantMatrixType> {};
+
+class DependentSizedMatrixTypeLoc
+ : public InheritingConcreteTypeLoc<MatrixTypeLoc,
+ DependentSizedMatrixTypeLoc,
+ DependentSizedMatrixType> {};
+
// FIXME: location of the '_Complex' keyword.
class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
ComplexTypeLoc,
@@ -1923,8 +1993,137 @@ class DeducedTypeLoc
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
DeducedType> {};
+struct AutoTypeLocInfo : TypeSpecLocInfo {
+ NestedNameSpecifierLoc NestedNameSpec;
+ SourceLocation TemplateKWLoc;
+ SourceLocation ConceptNameLoc;
+ NamedDecl *FoundDecl;
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
+};
+
class AutoTypeLoc
- : public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, AutoType> {
+ : public ConcreteTypeLoc<DeducedTypeLoc,
+ AutoTypeLoc,
+ AutoType,
+ AutoTypeLocInfo> {
+public:
+ AutoTypeKeyword getAutoKeyword() const {
+ return getTypePtr()->getKeyword();
+ }
+
+ bool isConstrained() const {
+ return getTypePtr()->isConstrained();
+ }
+
+ const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
+ return getLocalData()->NestedNameSpec;
+ }
+
+ void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+ getLocalData()->NestedNameSpec = NNS;
+ }
+
+ SourceLocation getTemplateKWLoc() const {
+ return getLocalData()->TemplateKWLoc;
+ }
+
+ void setTemplateKWLoc(SourceLocation Loc) {
+ getLocalData()->TemplateKWLoc = Loc;
+ }
+
+ SourceLocation getConceptNameLoc() const {
+ return getLocalData()->ConceptNameLoc;
+ }
+
+ void setConceptNameLoc(SourceLocation Loc) {
+ getLocalData()->ConceptNameLoc = Loc;
+ }
+
+ NamedDecl *getFoundDecl() const {
+ return getLocalData()->FoundDecl;
+ }
+
+ void setFoundDecl(NamedDecl *D) {
+ getLocalData()->FoundDecl = D;
+ }
+
+ ConceptDecl *getNamedConcept() const {
+ return getTypePtr()->getTypeConstraintConcept();
+ }
+
+ DeclarationNameInfo getConceptNameInfo() const;
+
+ bool hasExplicitTemplateArgs() const {
+ return getLocalData()->LAngleLoc.isValid();
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return this->getLocalData()->LAngleLoc;
+ }
+
+ void setLAngleLoc(SourceLocation Loc) {
+ this->getLocalData()->LAngleLoc = Loc;
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return this->getLocalData()->RAngleLoc;
+ }
+
+ void setRAngleLoc(SourceLocation Loc) {
+ this->getLocalData()->RAngleLoc = Loc;
+ }
+
+ unsigned getNumArgs() const {
+ return getTypePtr()->getNumArgs();
+ }
+
+ void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
+ getArgInfos()[i] = AI;
+ }
+
+ TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
+ return getArgInfos()[i];
+ }
+
+ TemplateArgumentLoc getArgLoc(unsigned i) const {
+ return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i],
+ getArgLocInfo(i));
+ }
+
+ SourceRange getLocalSourceRange() const {
+ return{
+ isConstrained()
+ ? (getNestedNameSpecifierLoc()
+ ? getNestedNameSpecifierLoc().getBeginLoc()
+ : (getTemplateKWLoc().isValid()
+ ? getTemplateKWLoc()
+ : getConceptNameLoc()))
+ : getNameLoc(),
+ getNameLoc()
+ };
+ }
+
+ void copy(AutoTypeLoc Loc) {
+ unsigned size = getFullDataSize();
+ assert(size == Loc.getFullDataSize());
+ memcpy(Data, Loc.Data, size);
+ }
+
+ void initializeLocal(ASTContext &Context, SourceLocation Loc);
+
+ unsigned getExtraLocalDataSize() const {
+ return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+ }
+
+ unsigned getExtraLocalDataAlignment() const {
+ return alignof(TemplateArgumentLocInfo);
+ }
+
+private:
+ TemplateArgumentLocInfo *getArgInfos() const {
+ return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+ }
};
class DeducedTemplateSpecializationTypeLoc
@@ -2314,6 +2513,12 @@ inline T TypeLoc::getAsAdjusted() const {
}
return Cur.getAs<T>();
}
+class ExtIntTypeLoc final
+ : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ExtIntTypeLoc,
+ ExtIntType> {};
+class DependentExtIntTypeLoc final
+ : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentExtIntTypeLoc,
+ DependentExtIntType> {};
} // namespace clang
diff --git a/clang/include/clang/AST/TypeLocVisitor.h b/clang/include/clang/AST/TypeLocVisitor.h
index ec780884e96c..168e9ac532ee 100644
--- a/clang/include/clang/AST/TypeLocVisitor.h
+++ b/clang/include/clang/AST/TypeLocVisitor.h
@@ -13,7 +13,6 @@
#define LLVM_CLANG_AST_TYPELOCVISITOR_H
#include "clang/AST/TypeLoc.h"
-#include "clang/AST/TypeVisitor.h"
#include "llvm/Support/ErrorHandling.h"
namespace clang {
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 4df2e2f77e2b..4540ea0e1952 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -224,6 +224,41 @@ let Class = DependentSizedExtVectorType in {
}]>;
}
+let Class = MatrixType in {
+ def : Property<"elementType", QualType> {
+ let Read = [{ node->getElementType() }];
+ }
+}
+
+let Class = ConstantMatrixType in {
+ def : Property<"numRows", UInt32> {
+ let Read = [{ node->getNumRows() }];
+ }
+ def : Property<"numColumns", UInt32> {
+ let Read = [{ node->getNumColumns() }];
+ }
+
+ def : Creator<[{
+ return ctx.getConstantMatrixType(elementType, numRows, numColumns);
+ }]>;
+}
+
+let Class = DependentSizedMatrixType in {
+ def : Property<"rows", ExprRef> {
+ let Read = [{ node->getRowExpr() }];
+ }
+ def : Property<"columns", ExprRef> {
+ let Read = [{ node->getColumnExpr() }];
+ }
+ def : Property<"attributeLoc", SourceLocation> {
+ let Read = [{ node->getAttributeLoc() }];
+ }
+
+ def : Creator<[{
+ return ctx.getDependentSizedMatrixType(elementType, rows, columns, attributeLoc);
+ }]>;
+}
+
let Class = FunctionType in {
def : Property<"returnType", QualType> {
let Read = [{ node->getReturnType() }];
@@ -249,13 +284,17 @@ let Class = FunctionType in {
def : Property<"noCfCheck", Bool> {
let Read = [{ node->getExtInfo().getNoCfCheck() }];
}
+ def : Property<"cmseNSCall", Bool> {
+ let Read = [{ node->getExtInfo().getCmseNSCall() }];
+ }
}
let Class = FunctionNoProtoType in {
def : Creator<[{
auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm,
callingConvention, producesResult,
- noCallerSavedRegs, noCfCheck);
+ noCallerSavedRegs, noCfCheck,
+ cmseNSCall);
return ctx.getFunctionNoProtoType(returnType, extInfo);
}]>;
}
@@ -288,7 +327,8 @@ let Class = FunctionProtoType in {
def : Creator<[{
auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm,
callingConvention, producesResult,
- noCallerSavedRegs, noCfCheck);
+ noCallerSavedRegs, noCfCheck,
+ cmseNSCall);
FunctionProtoType::ExtProtoInfo epi;
epi.ExtInfo = extInfo;
epi.Variadic = variadic;
@@ -395,6 +435,13 @@ let Class = AutoType in {
def : Property<"keyword", AutoTypeKeyword> {
let Read = [{ node->getKeyword() }];
}
+ def : Property<"typeConstraintConcept", Optional<ConceptDeclRef>> {
+ let Read = [{ makeOptionalFromPointer(
+ const_cast<const ConceptDecl*>(node->getTypeConstraintConcept())) }];
+ }
+ def : Property<"typeConstraintArguments", Array<TemplateArgument>> {
+ let Read = [{ node->getTypeConstraintArguments() }];
+ }
// FIXME: better enumerated value
// Only really required when the deduced type is null
def : Property<"dependence", UInt32> {
@@ -406,7 +453,9 @@ let Class = AutoType in {
def : Creator<[{
return ctx.getAutoType(makeNullableFromOptional(deducedType), keyword,
/*isDependentWithoutDeducedType*/ dependence > 0,
- /*isPackWithoutDeducedType*/ dependence > 1);
+ /*isPackWithoutDeducedType*/ dependence > 1,
+ makePointerFromOptional(typeConstraintConcept),
+ typeConstraintArguments);
}]>;
}
@@ -444,7 +493,9 @@ let Class = TagType in {
let Class = EnumType in {
def : Creator<[{
QualType result = ctx.getEnumType(cast<EnumDecl>(declaration));
- const_cast<Type*>(result.getTypePtr())->setDependent(dependent);
+ if (dependent)
+ const_cast<Type *>(result.getTypePtr())
+ ->addDependence(TypeDependence::DependentInstantiation);
return result;
}]>;
}
@@ -453,7 +504,9 @@ let Class = RecordType in {
def : Creator<[{
auto record = cast<RecordDecl>(declaration);
QualType result = ctx.getRecordType(record);
- const_cast<Type*>(result.getTypePtr())->setDependent(dependent);
+ if (dependent)
+ const_cast<Type *>(result.getTypePtr())
+ ->addDependence(TypeDependence::DependentInstantiation);
return result;
}]>;
}
@@ -596,7 +649,9 @@ let Class = TemplateSpecializationType in {
templateArguments,
*underlyingType);
}
- const_cast<Type*>(result.getTypePtr())->setDependent(dependent);
+ if (dependent)
+ const_cast<Type *>(result.getTypePtr())
+ ->addDependence(TypeDependence::DependentInstantiation);
return result;
}]>;
}
@@ -813,3 +868,28 @@ let Class = PipeType in {
return ctx.getPipeType(elementType, isReadOnly);
}]>;
}
+
+let Class = ExtIntType in {
+ def : Property<"isUnsigned", Bool> {
+ let Read = [{ node->isUnsigned() }];
+ }
+ def : Property <"numBits", UInt32> {
+ let Read = [{ node->getNumBits() }];
+ }
+
+ def : Creator<[{
+ return ctx.getExtIntType(isUnsigned, numBits);
+ }]>;
+}
+
+let Class = DependentExtIntType in {
+ def : Property<"isUnsigned", Bool> {
+ let Read = [{ node->isUnsigned() }];
+ }
+ def : Property <"numBitsExpr", ExprRef> {
+ let Read = [{ node->getNumBitsExpr() }];
+ }
+ def : Creator<[{
+ return ctx.getDependentExtIntType(isUnsigned, numBitsExpr);
+ }]>;
+}
diff --git a/clang/include/clang/AST/VTableBuilder.h b/clang/include/clang/AST/VTableBuilder.h
index 43c84292c091..241dd13f903e 100644
--- a/clang/include/clang/AST/VTableBuilder.h
+++ b/clang/include/clang/AST/VTableBuilder.h
@@ -238,6 +238,11 @@ public:
typedef llvm::DenseMap<BaseSubobject, AddressPointLocation>
AddressPointsMapTy;
+ // Mapping between the VTable index and address point index. This is useful
+ // when you don't care about the base subobjects and only want the address
+ // point for a given vtable index.
+ typedef llvm::SmallVector<unsigned, 4> AddressPointsIndexMapTy;
+
private:
// Stores the component indices of the first component of each virtual table in
// the virtual table group. To save a little memory in the common case where
@@ -253,6 +258,9 @@ private:
/// Address points for all vtables.
AddressPointsMapTy AddressPoints;
+ /// Address points for all vtable indices.
+ AddressPointsIndexMapTy AddressPointIndices;
+
public:
VTableLayout(ArrayRef<size_t> VTableIndices,
ArrayRef<VTableComponent> VTableComponents,
@@ -277,6 +285,10 @@ public:
return AddressPoints;
}
+ const AddressPointsIndexMapTy &getAddressPointIndices() const {
+ return AddressPointIndices;
+ }
+
size_t getNumVTables() const {
if (VTableIndices.empty())
return 1;
@@ -342,6 +354,9 @@ public:
}
bool IsMicrosoftABI;
+
+ /// Determine whether this function should be assigned a vtable slot.
+ static bool hasVtableSlot(const CXXMethodDecl *MD);
};
class ItaniumVTableContext : public VTableContextBase {
@@ -371,7 +386,17 @@ private:
void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
public:
- ItaniumVTableContext(ASTContext &Context);
+ enum VTableComponentLayout {
+ /// Components in the vtable are pointers to other structs/functions.
+ Pointer,
+
+ /// Components in the vtable are relative offsets between the vtable and the
+ /// other structs/functions.
+ Relative,
+ };
+
+ ItaniumVTableContext(ASTContext &Context,
+ VTableComponentLayout ComponentLayout = Pointer);
~ItaniumVTableContext() override;
const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) {
@@ -402,6 +427,16 @@ public:
static bool classof(const VTableContextBase *VT) {
return !VT->isMicrosoft();
}
+
+ VTableComponentLayout getVTableComponentLayout() const {
+ return ComponentLayout;
+ }
+
+ bool isPointerLayout() const { return ComponentLayout == Pointer; }
+ bool isRelativeLayout() const { return ComponentLayout == Relative; }
+
+private:
+ VTableComponentLayout ComponentLayout;
};
/// Holds information about the inheritance path to a virtual base or function