aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTContext.h111
-rw-r--r--include/clang/AST/ASTDiagnostic.h4
-rw-r--r--include/clang/AST/ASTFwd.h5
-rw-r--r--include/clang/AST/ASTLambda.h6
-rw-r--r--include/clang/AST/ASTMutationListener.h6
-rw-r--r--include/clang/AST/ASTTypeTraits.h50
-rw-r--r--include/clang/AST/ASTVector.h23
-rw-r--r--include/clang/AST/Attr.h1
-rw-r--r--include/clang/AST/CanonicalType.h6
-rw-r--r--include/clang/AST/Comment.h10
-rw-r--r--include/clang/AST/CommentBriefParser.h4
-rw-r--r--include/clang/AST/CommentCommandTraits.h10
-rw-r--r--include/clang/AST/CommentDiagnostic.h4
-rw-r--r--include/clang/AST/CommentLexer.h4
-rw-r--r--include/clang/AST/CommentParser.h4
-rw-r--r--include/clang/AST/CommentSema.h6
-rw-r--r--include/clang/AST/DataRecursiveASTVisitor.h149
-rw-r--r--include/clang/AST/Decl.h153
-rw-r--r--include/clang/AST/DeclBase.h21
-rw-r--r--include/clang/AST/DeclCXX.h103
-rw-r--r--include/clang/AST/DeclFriend.h4
-rw-r--r--include/clang/AST/DeclObjC.h21
-rw-r--r--include/clang/AST/DeclOpenMP.h10
-rw-r--r--include/clang/AST/DeclTemplate.h8
-rw-r--r--include/clang/AST/DeclarationName.h1
-rw-r--r--include/clang/AST/DependentDiagnostic.h4
-rw-r--r--include/clang/AST/Expr.h102
-rw-r--r--include/clang/AST/ExprCXX.h117
-rw-r--r--include/clang/AST/ExternalASTSource.h6
-rw-r--r--include/clang/AST/LambdaCapture.h12
-rw-r--r--include/clang/AST/Mangle.h5
-rw-r--r--include/clang/AST/MangleNumberingContext.h17
-rw-r--r--include/clang/AST/NSAPI.h10
-rw-r--r--include/clang/AST/NestedNameSpecifier.h34
-rw-r--r--include/clang/AST/OpenMPClause.h429
-rw-r--r--include/clang/AST/OperationKinds.h4
-rw-r--r--include/clang/AST/ParentMap.h4
-rw-r--r--include/clang/AST/PrettyPrinter.h4
-rw-r--r--include/clang/AST/RawCommentList.h4
-rw-r--r--include/clang/AST/RecordLayout.h4
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h149
-rw-r--r--include/clang/AST/Stmt.h80
-rw-r--r--include/clang/AST/StmtGraphTraits.h4
-rw-r--r--include/clang/AST/StmtIterator.h4
-rw-r--r--include/clang/AST/StmtOpenMP.h1063
-rw-r--r--include/clang/AST/TemplateBase.h21
-rw-r--r--include/clang/AST/Type.h99
-rw-r--r--include/clang/AST/TypeLoc.h4
-rw-r--r--include/clang/AST/TypeOrdering.h4
-rw-r--r--include/clang/AST/UnresolvedSet.h2
50 files changed, 2511 insertions, 399 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 0a991cc4ce..ef87fa6dd9 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -30,6 +30,7 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SanitizerBlacklist.h"
#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
@@ -74,6 +75,15 @@ namespace clang {
class FullComment;
}
+ struct TypeInfo {
+ uint64_t Width;
+ unsigned Align;
+ bool AlignIsRequired : 1;
+ TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
+ TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
+ : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
+ };
+
/// \brief Holds long-lived AST nodes (such as types and decls) that can be
/// referred to throughout the semantic analysis of a file.
class ASTContext : public RefCountedBase<ASTContext> {
@@ -144,8 +154,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
ObjCLayouts;
/// \brief A cache from types to size and alignment information.
- typedef llvm::DenseMap<const Type*,
- std::pair<uint64_t, unsigned> > TypeInfoMap;
+ typedef llvm::DenseMap<const Type *, struct TypeInfo> TypeInfoMap;
mutable TypeInfoMap MemoizedTypeInfo;
/// \brief A cache mapping from CXXRecordDecls to key functions.
@@ -384,6 +393,10 @@ private:
/// this ASTContext object.
LangOptions &LangOpts;
+ /// \brief Blacklist object that is used by sanitizers to decide which
+ /// entities should not be instrumented.
+ std::unique_ptr<SanitizerBlacklist> SanitizerBL;
+
/// \brief The allocator used to create AST objects.
///
/// AST objects are never destructed; rather, all memory associated with the
@@ -453,11 +466,12 @@ public:
/// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
/// NestedNameSpecifier or NestedNameSpecifierLoc.
template <typename NodeT>
- ParentVector getParents(const NodeT &Node) {
+ ArrayRef<ast_type_traits::DynTypedNode> getParents(const NodeT &Node) {
return getParents(ast_type_traits::DynTypedNode::create(Node));
}
- ParentVector getParents(const ast_type_traits::DynTypedNode &Node);
+ ArrayRef<ast_type_traits::DynTypedNode>
+ getParents(const ast_type_traits::DynTypedNode &Node);
const clang::PrintingPolicy &getPrintingPolicy() const {
return PrintingPolicy;
@@ -508,6 +522,10 @@ public:
const LangOptions& getLangOpts() const { return LangOpts; }
+ const SanitizerBlacklist &getSanitizerBlacklist() const {
+ return *SanitizerBL;
+ }
+
DiagnosticsEngine &getDiagnostics() const;
FullSourceLoc getFullLoc(SourceLocation Loc) const {
@@ -912,6 +930,12 @@ public:
/// \brief Change the result type of a function type once it is deduced.
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
+ /// \brief Change the exception specification on a function once it is
+ /// delay-parsed, instantiated, or computed.
+ void adjustExceptionSpec(FunctionDecl *FD,
+ const FunctionProtoType::ExceptionSpecInfo &ESI,
+ bool AsWritten = false);
+
/// \brief Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType getComplexType(QualType T) const;
@@ -1371,7 +1395,8 @@ public:
///
/// If \p Field is specified then record field names are also encoded.
void getObjCEncodingForType(QualType T, std::string &S,
- const FieldDecl *Field=nullptr) const;
+ const FieldDecl *Field=nullptr,
+ QualType *NotEncodedT=nullptr) const;
/// \brief Emit the Objective-C property type encoding for the given
/// type \p T into \p S.
@@ -1581,7 +1606,7 @@ public:
private:
CanQualType getFromTargetType(unsigned Type) const;
- std::pair<uint64_t, unsigned> getTypeInfoImpl(const Type *T) const;
+ TypeInfo getTypeInfoImpl(const Type *T) const;
//===--------------------------------------------------------------------===//
// Type Predicates.
@@ -1614,18 +1639,12 @@ public:
const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;
/// \brief Get the size and alignment of the specified complete type in bits.
- std::pair<uint64_t, unsigned> getTypeInfo(const Type *T) const;
- std::pair<uint64_t, unsigned> getTypeInfo(QualType T) const {
- return getTypeInfo(T.getTypePtr());
- }
+ TypeInfo getTypeInfo(const Type *T) const;
+ TypeInfo getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); }
/// \brief Return the size of the specified (complete) type \p T, in bits.
- uint64_t getTypeSize(QualType T) const {
- return getTypeInfo(T).first;
- }
- uint64_t getTypeSize(const Type *T) const {
- return getTypeInfo(T).first;
- }
+ uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).Width; }
+ uint64_t getTypeSize(const Type *T) const { return getTypeInfo(T).Width; }
/// \brief Return the size of the character type, in bits.
uint64_t getCharWidth() const {
@@ -1645,12 +1664,8 @@ public:
/// \brief Return the ABI-specified alignment of a (complete) type \p T, in
/// bits.
- unsigned getTypeAlign(QualType T) const {
- return getTypeInfo(T).second;
- }
- unsigned getTypeAlign(const Type *T) const {
- return getTypeInfo(T).second;
- }
+ unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; }
+ unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).Align; }
/// \brief Return the ABI-specified alignment of a (complete) type \p T, in
/// characters.
@@ -1664,6 +1679,11 @@ public:
std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T) const;
std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T) const;
+ /// \brief Determine if the alignment the type has was required using an
+ /// alignment attribute.
+ bool isAlignmentRequired(const Type *T) const;
+ bool isAlignmentRequired(QualType T) const;
+
/// \brief Return the "preferred" alignment of the specified type \p T for
/// the current target, in bits.
///
@@ -2272,17 +2292,23 @@ private:
bool StructField = false,
bool EncodeBlockParameters = false,
bool EncodeClassNames = false,
- bool EncodePointerToObjCTypedef = false) const;
+ bool EncodePointerToObjCTypedef = false,
+ QualType *NotEncodedT=nullptr) const;
// Adds the encoding of the structure's members.
void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
const FieldDecl *Field,
- bool includeVBases = true) const;
+ bool includeVBases = true,
+ QualType *NotEncodedT=nullptr) const;
public:
// Adds the encoding of a method parameter or return type.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
QualType T, std::string& S,
bool Extended) const;
+
+ /// \brief Returns true if this is an inline-initialized static data member
+ /// which is treated as a definition for MSVC compatibility.
+ bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
private:
const ASTRecordLayout &
@@ -2308,6 +2334,31 @@ private:
std::unique_ptr<ParentMap> AllParents;
std::unique_ptr<VTableContextBase> VTContext;
+
+public:
+ enum PragmaSectionFlag : unsigned {
+ PSF_None = 0,
+ PSF_Read = 0x1,
+ PSF_Write = 0x2,
+ PSF_Execute = 0x4,
+ PSF_Implicit = 0x8,
+ PSF_Invalid = 0x80000000U,
+ };
+
+ struct SectionInfo {
+ DeclaratorDecl *Decl;
+ SourceLocation PragmaSectionLocation;
+ int SectionFlags;
+ SectionInfo() {}
+ SectionInfo(DeclaratorDecl *Decl,
+ SourceLocation PragmaSectionLocation,
+ int SectionFlags)
+ : Decl(Decl),
+ PragmaSectionLocation(PragmaSectionLocation),
+ SectionFlags(SectionFlags) {}
+ };
+
+ llvm::StringMap<SectionInfo> SectionInfos;
};
/// \brief Utility function for constructing a nullary selector.
@@ -2345,9 +2396,9 @@ static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
/// // Specific alignment
/// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments);
/// @endcode
-/// Please note that you cannot use delete on the pointer; it must be
-/// deallocated using an explicit destructor call followed by
-/// @c Context.Deallocate(Ptr).
+/// Memory allocated through this placement new operator does not need to be
+/// explicitly freed, as ASTContext will free all of this memory when it gets
+/// destroyed. Please note that you cannot use delete on the pointer.
///
/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
/// @param C The ASTContext that provides the allocator.
@@ -2382,9 +2433,9 @@ inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
/// // Specific alignment
/// char *data = new (Context, 4) char[10];
/// @endcode
-/// Please note that you cannot use delete on the pointer; it must be
-/// deallocated using an explicit destructor call followed by
-/// @c Context.Deallocate(Ptr).
+/// Memory allocated through this placement new[] operator does not need to be
+/// explicitly freed, as ASTContext will free all of this memory when it gets
+/// destroyed. Please note that you cannot use delete on the pointer.
///
/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
/// @param C The ASTContext that provides the allocator.
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 484ca4cb86..27c85e65f2 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_DIAGNOSTICAST_H
-#define LLVM_CLANG_DIAGNOSTICAST_H
+#ifndef LLVM_CLANG_AST_ASTDIAGNOSTIC_H
+#define LLVM_CLANG_AST_ASTDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h
index 4f3279874b..003d489c1c 100644
--- a/include/clang/AST/ASTFwd.h
+++ b/include/clang/AST/ASTFwd.h
@@ -12,6 +12,9 @@
///
//===-------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_ASTFWD_H
+#define LLVM_CLANG_AST_ASTFWD_H
+
namespace clang {
class Decl;
@@ -26,3 +29,5 @@ class Type;
class CXXCtorInitializer;
} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
index 9af016b13d..69df2d8c01 100644
--- a/include/clang/AST/ASTLambda.h
+++ b/include/clang/AST/ASTLambda.h
@@ -13,8 +13,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_LAMBDA_H
-#define LLVM_CLANG_AST_LAMBDA_H
+#ifndef LLVM_CLANG_AST_ASTLAMBDA_H
+#define LLVM_CLANG_AST_ASTLAMBDA_H
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
@@ -77,4 +77,4 @@ inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) {
} // clang
-#endif // LLVM_CLANG_AST_LAMBDA_H
+#endif
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index a89bfed53f..48eb629277 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -102,6 +102,12 @@ public:
/// \param D the declaration marked used
virtual void DeclarationMarkedUsed(const Decl *D) {}
+ /// \brief A declaration is marked as OpenMP threadprivate which was not
+ /// previously marked as threadprivate.
+ ///
+ /// \param D the declaration marked OpenMP threadprivate.
+ virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {}
+
// NOTE: If new methods are added they should also be added to
// MultiplexASTMutationListener.
};
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index 0e06e26e6d..efeac563db 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H
-#define LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+#ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
+#define LLVM_CLANG_AST_ASTTYPETRAITS_H
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Decl.h"
@@ -53,9 +53,19 @@ public:
return ASTNodeKind(KindToKindId<T>::Id);
}
+ /// \{
+ /// \brief Construct an identifier for the dynamic type of the node
+ static ASTNodeKind getFromNode(const Decl &D);
+ static ASTNodeKind getFromNode(const Stmt &S);
+ static ASTNodeKind getFromNode(const Type &T);
+ /// \}
+
/// \brief Returns \c true if \c this and \c Other represent the same kind.
bool isSame(ASTNodeKind Other) const;
+ /// \brief Returns \c true only for the default \c ASTNodeKind()
+ bool isNone() const { return KindId == NKI_None; }
+
/// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
/// \param Distance If non-null, used to return the distance between \c this
/// and \c Other in the class hierarchy.
@@ -69,6 +79,17 @@ public:
return KindId < Other.KindId;
}
+ /// \brief Return the most derived type between \p Kind1 and \p Kind2.
+ ///
+ /// Return ASTNodeKind() if they are not related.
+ static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2);
+
+ /// \brief Return the most derived common ancestor between Kind1 and Kind2.
+ ///
+ /// Return ASTNodeKind() if they are not related.
+ static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
+ ASTNodeKind Kind2);
+
private:
/// \brief Kind ids.
///
@@ -184,12 +205,14 @@ public:
return BaseConverter<T>::get(NodeKind, Storage.buffer);
}
+ ASTNodeKind getNodeKind() const { return NodeKind; }
+
/// \brief Returns a pointer that identifies the stored AST node.
///
/// Note that this is not supported by all AST nodes. For AST nodes
/// that don't have a pointer-defined identity inside the AST, this
/// method returns NULL.
- const void *getMemoizationData() const;
+ const void *getMemoizationData() const { return MemoizationData; }
/// \brief Prints the node to the given output stream.
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
@@ -241,7 +264,8 @@ private:
}
static DynTypedNode create(const BaseT &Node) {
DynTypedNode Result;
- Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+ Result.NodeKind = ASTNodeKind::getFromNode(Node);
+ Result.MemoizationData = &Node;
new (Result.Storage.buffer) const BaseT * (&Node);
return Result;
}
@@ -257,6 +281,7 @@ private:
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+ Result.MemoizationData = &Node;
new (Result.Storage.buffer) const T * (&Node);
return Result;
}
@@ -272,12 +297,14 @@ private:
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+ Result.MemoizationData = nullptr;
new (Result.Storage.buffer) T(Node);
return Result;
}
};
ASTNodeKind NodeKind;
+ const void *MemoizationData;
/// \brief Stores the data of the node.
///
@@ -345,20 +372,7 @@ template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
}
};
-inline const void *DynTypedNode::getMemoizationData() const {
- if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(NodeKind)) {
- return BaseConverter<Decl>::get(NodeKind, Storage.buffer);
- } else if (ASTNodeKind::getFromNodeKind<Stmt>().isBaseOf(NodeKind)) {
- return BaseConverter<Stmt>::get(NodeKind, Storage.buffer);
- } else if (ASTNodeKind::getFromNodeKind<Type>().isBaseOf(NodeKind)) {
- return BaseConverter<Type>::get(NodeKind, Storage.buffer);
- } else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) {
- return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer);
- }
- return nullptr;
-}
-
} // end namespace ast_type_traits
} // end namespace clang
-#endif // LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+#endif
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index d92167e959..6ec054582e 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -15,8 +15,8 @@
// FIXME: Most of this is copy-and-paste from BumpVector.h and SmallVector.h.
// We can refactor this core logic into something common.
-#ifndef LLVM_CLANG_AST_VECTOR
-#define LLVM_CLANG_AST_VECTOR
+#ifndef LLVM_CLANG_AST_ASTVECTOR_H
+#define LLVM_CLANG_AST_ASTVECTOR_H
#include "clang/AST/AttrIterator.h"
#include "llvm/ADT/PointerIntPair.h"
@@ -236,14 +236,14 @@ public:
iterator insert(const ASTContext &C, iterator I, size_type NumToInsert,
const T &Elt) {
- if (I == this->end()) { // Important special case for empty vector.
- append(C, NumToInsert, Elt);
- return this->end()-1;
- }
-
// Convert iterator to elt# to avoid invalidating iterator when we reserve()
size_t InsertElt = I - this->begin();
+ if (I == this->end()) { // Important special case for empty vector.
+ append(C, NumToInsert, Elt);
+ return this->begin() + InsertElt;
+ }
+
// Ensure there is enough space.
reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
@@ -284,14 +284,15 @@ public:
template<typename ItTy>
iterator insert(const ASTContext &C, iterator I, ItTy From, ItTy To) {
- if (I == this->end()) { // Important special case for empty vector.
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I - this->begin();
+
+ if (I == this->end()) { // Important special case for empty vector.
append(C, From, To);
- return this->end()-1;
+ return this->begin() + InsertElt;
}
size_t NumToInsert = std::distance(From, To);
- // Convert iterator to elt# to avoid invalidating iterator when we reserve()
- size_t InsertElt = I - this->begin();
// Ensure there is enough space.
reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index fc4881619b..787843e64f 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -16,6 +16,7 @@
#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/LLVM.h"
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 7cccef69dd..aa3c846829 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_CANONICAL_TYPE_H
-#define LLVM_CLANG_AST_CANONICAL_TYPE_H
+#ifndef LLVM_CLANG_AST_CANONICALTYPE_H
+#define LLVM_CLANG_AST_CANONICALTYPE_H
#include "clang/AST/Type.h"
#include "llvm/Support/Casting.h"
@@ -736,4 +736,4 @@ CanTypeIterator<InputIterator>::operator->() const {
}
-#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
+#endif
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index e18fe9ab86..94470cbf30 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -96,9 +96,10 @@ protected:
unsigned : NumInlineContentCommentBits;
unsigned RenderKind : 2;
- unsigned CommandID : 8;
+ unsigned CommandID : CommandInfo::NumCommandIDBits;
};
- enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 };
+ enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 2 +
+ CommandInfo::NumCommandIDBits };
class HTMLTagCommentBitfields {
friend class HTMLTagComment;
@@ -139,13 +140,14 @@ protected:
unsigned : NumCommentBits;
- unsigned CommandID : 8;
+ unsigned CommandID : CommandInfo::NumCommandIDBits;
/// Describes the syntax that was used in a documentation command.
/// Contains values from CommandMarkerKind enum.
unsigned CommandMarker : 1;
};
- enum { NumBlockCommandCommentBits = NumCommentBits + 9 };
+ enum { NumBlockCommandCommentBits = NumCommentBits +
+ CommandInfo::NumCommandIDBits + 1 };
class ParamCommandCommentBitfields {
friend class ParamCommandComment;
diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h
index 5d50886063..be5b8eeb80 100644
--- a/include/clang/AST/CommentBriefParser.h
+++ b/include/clang/AST/CommentBriefParser.h
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_BRIEF_COMMENT_PARSER_H
-#define LLVM_CLANG_AST_BRIEF_COMMENT_PARSER_H
+#ifndef LLVM_CLANG_AST_COMMENTBRIEFPARSER_H
+#define LLVM_CLANG_AST_COMMENTBRIEFPARSER_H
#include "clang/AST/CommentLexer.h"
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
index dde7a1442f..ec6d83c030 100644
--- a/include/clang/AST/CommentCommandTraits.h
+++ b/include/clang/AST/CommentCommandTraits.h
@@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
-#define LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
+#ifndef LLVM_CLANG_AST_COMMENTCOMMANDTRAITS_H
+#define LLVM_CLANG_AST_COMMENTCOMMANDTRAITS_H
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/LLVM.h"
@@ -40,7 +40,11 @@ struct CommandInfo {
/// Name of the command that ends the verbatim block.
const char *EndCommandName;
- unsigned ID : 8;
+ /// DRY definition of the number of bits used for a command ID.
+ enum { NumCommandIDBits = 20 };
+
+ /// The ID of the command.
+ unsigned ID : NumCommandIDBits;
/// Number of word-like arguments for a given block command, except for
/// \\param and \\tparam commands -- these have special argument parsers.
diff --git a/include/clang/AST/CommentDiagnostic.h b/include/clang/AST/CommentDiagnostic.h
index 312da065ff..f3a209bf6e 100644
--- a/include/clang/AST/CommentDiagnostic.h
+++ b/include/clang/AST/CommentDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_COMMENTDIAGNOSTIC_H
-#define LLVM_CLANG_COMMENTDIAGNOSTIC_H
+#ifndef LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
+#define LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index a6e3ed89b2..d995df9212 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_COMMENT_LEXER_H
-#define LLVM_CLANG_AST_COMMENT_LEXER_H
+#ifndef LLVM_CLANG_AST_COMMENTLEXER_H
+#define LLVM_CLANG_AST_COMMENTLEXER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
index 7e008131d2..2c444f0dc3 100644
--- a/include/clang/AST/CommentParser.h
+++ b/include/clang/AST/CommentParser.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_COMMENT_PARSER_H
-#define LLVM_CLANG_AST_COMMENT_PARSER_H
+#ifndef LLVM_CLANG_AST_COMMENTPARSER_H
+#define LLVM_CLANG_AST_COMMENTPARSER_H
#include "clang/AST/Comment.h"
#include "clang/AST/CommentLexer.h"
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index 027c3b929d..4ae6fe0c61 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_COMMENT_SEMA_H
-#define LLVM_CLANG_AST_COMMENT_SEMA_H
+#ifndef LLVM_CLANG_AST_COMMENTSEMA_H
+#define LLVM_CLANG_AST_COMMENTSEMA_H
#include "clang/AST/Comment.h"
#include "clang/Basic/Diagnostic.h"
@@ -85,7 +85,7 @@ public:
std::uninitialized_copy(Source.begin(), Source.end(), Mem);
return llvm::makeArrayRef(Mem, Size);
}
- return ArrayRef<T>();
+ return None;
}
ParagraphComment *actOnParagraphComment(
diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h
index e2dcdbe392..c0526e1cfd 100644
--- a/include/clang/AST/DataRecursiveASTVisitor.h
+++ b/include/clang/AST/DataRecursiveASTVisitor.h
@@ -424,6 +424,7 @@ private:
bool TraverseFunctionHelper(FunctionDecl *D);
bool TraverseVarHelper(VarDecl *D);
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"
@@ -623,6 +624,7 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Super:
return true;
case NestedNameSpecifier::TypeSpec:
@@ -647,6 +649,7 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Super:
return true;
case NestedNameSpecifier::TypeSpec:
@@ -875,6 +878,9 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
for (const auto &E : T->exceptions()) {
TRY_TO(TraverseType(E));
}
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
})
DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
@@ -1083,6 +1089,9 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
for (const auto &E : T->exceptions()) {
TRY_TO(TraverseType(E));
}
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
})
DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
@@ -2122,21 +2131,29 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
TRY_TO(TraverseLambdaCapture(S, C));
}
- if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
- // Visit the whole type.
- TRY_TO(TraverseTypeLoc(TL));
- } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
- if (S->hasExplicitParameters()) {
- // Visit parameters.
- for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
- TRY_TO(TraverseDecl(Proto.getParam(I)));
- }
- } else {
- TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
+ TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+ FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
+
+ if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+ // Visit the whole type.
+ TRY_TO(TraverseTypeLoc(TL));
+ } else {
+ if (S->hasExplicitParameters()) {
+ // Visit parameters.
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+ TRY_TO(TraverseDecl(Proto.getParam(I)));
}
+ } else if (S->hasExplicitResultType()) {
+ TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
}
+
+ auto *T = Proto.getTypePtr();
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
}
TRY_TO(TraverseLambdaBody(S));
@@ -2237,6 +2254,7 @@ DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(TypoExpr, {})
DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
// These operators (all of them) do not need any action except
@@ -2253,6 +2271,7 @@ DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXFoldExpr, {})
DEF_TRAVERSE_STMT(AtomicExpr, {})
// These literals (all of them) do not need any action.
@@ -2279,6 +2298,12 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
return true;
}
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
+ return TraverseOMPExecutableDirective(S);
+}
+
DEF_TRAVERSE_STMT(OMPParallelDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2288,6 +2313,9 @@ DEF_TRAVERSE_STMT(OMPSimdDirective,
DEF_TRAVERSE_STMT(OMPForDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPForSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2297,12 +2325,50 @@ DEF_TRAVERSE_STMT(OMPSectionDirective,
DEF_TRAVERSE_STMT(OMPSingleDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+ TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+ TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
DEF_TRAVERSE_STMT(OMPParallelForDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTaskDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPBarrierDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPOrderedDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPAtomicDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTeamsDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
@@ -2328,6 +2394,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
+ TRY_TO(TraverseStmt(C->getCondition()));
+ return true;
+}
+
+template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
TRY_TO(TraverseStmt(C->getNumThreads()));
@@ -2375,6 +2447,42 @@ bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
+ return true;
+}
+
+template <typename Derived>
template <typename T>
bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
for (auto *E : Node->varlists()) {
@@ -2386,6 +2494,9 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
TRY_TO(VisitOMPClauseList(C));
+ for (auto *E : C->private_copies()) {
+ TRY_TO(TraverseStmt(E));
+ }
return true;
}
@@ -2393,6 +2504,12 @@ template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
OMPFirstprivateClause *C) {
TRY_TO(VisitOMPClauseList(C));
+ for (auto *E : C->private_copies()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->inits()) {
+ TRY_TO(TraverseStmt(E));
+ }
return true;
}
@@ -2445,6 +2562,12 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ 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/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index ce8b8b7dbc..b946636ebd 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -43,6 +43,7 @@ class Stmt;
class StringLiteral;
class TemplateArgumentList;
class TemplateParameterList;
+class TypeAliasTemplateDecl;
class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;
@@ -67,6 +68,9 @@ public:
/// \brief Return the TypeLoc wrapper for the type source info.
TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
+
+ /// \brief Override the type stored in this TypeSourceInfo. Use with caution!
+ void overrideType(QualType T) { Ty = T; }
};
/// TranslationUnitDecl - The top declaration context.
@@ -288,6 +292,8 @@ public:
return const_cast<NamedDecl*>(this)->getMostRecentDecl();
}
+ ObjCStringFormatFamily getObjCFStringFormattingFamily() const;
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
};
@@ -305,6 +311,8 @@ inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
class LabelDecl : public NamedDecl {
void anchor() override;
LabelStmt *TheStmt;
+ StringRef MSAsmName;
+ bool MSAsmNameResolved;
/// LocStart - For normal labels, this is the same as the main declaration
/// label, i.e., the location of the identifier; for GNU local labels,
/// this is the location of the __label__ keyword.
@@ -312,7 +320,10 @@ class LabelDecl : public NamedDecl {
LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II,
LabelStmt *S, SourceLocation StartL)
- : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {}
+ : NamedDecl(Label, DC, IdentL, II),
+ TheStmt(S),
+ MSAsmNameResolved(false),
+ LocStart(StartL) {}
public:
static LabelDecl *Create(ASTContext &C, DeclContext *DC,
@@ -332,6 +343,12 @@ public:
return SourceRange(LocStart, getLocation());
}
+ bool isMSAsmLabel() const { return MSAsmName.size() != 0; }
+ bool isResolvedMSAsmLabel() const { return isMSAsmLabel() && MSAsmNameResolved; }
+ void setMSAsmLabel(StringRef Name);
+ StringRef getMSAsmLabel() const { return MSAsmName; }
+ void setMSAsmLabelResolved() { MSAsmNameResolved = true; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Label; }
@@ -648,8 +665,6 @@ struct EvaluatedStmt {
/// declaration or definition.
class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
public:
- typedef clang::StorageClass StorageClass;
-
/// getStorageClassSpecifierString - Return the string used to
/// specify the storage class \p SC.
///
@@ -1423,8 +1438,6 @@ private:
class FunctionDecl : public DeclaratorDecl, public DeclContext,
public Redeclarable<FunctionDecl> {
public:
- typedef clang::StorageClass StorageClass;
-
/// \brief The kind of templated function a FunctionDecl can be.
enum TemplatedKind {
TK_NonTemplate,
@@ -1650,7 +1663,7 @@ public:
/// unnecessary AST de-serialization of the body.
Stmt *getBody(const FunctionDecl *&Definition) const;
- Stmt *getBody() const override {
+ Stmt *getBody() const override {
const FunctionDecl* Definition;
return getBody(Definition);
}
@@ -1880,7 +1893,7 @@ public:
return llvm::makeArrayRef(ParamInfo, getNumParams());
}
- const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const {
+ ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const {
return DeclsInPrototypeScope;
}
void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls);
@@ -2154,17 +2167,41 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
bool Mutable : 1;
mutable unsigned CachedFieldIndex : 31;
- /// \brief An InClassInitStyle value, and either a bit width expression (if
- /// the InClassInitStyle value is ICIS_NoInit), or a pointer to the in-class
- /// initializer for this field (otherwise).
+ /// The kinds of value we can store in InitializerOrBitWidth.
+ ///
+ /// Note that this is compatible with InClassInitStyle except for
+ /// ISK_CapturedVLAType.
+ enum InitStorageKind {
+ /// If the pointer is null, there's nothing special. Otherwise,
+ /// this is a bitfield and the pointer is the Expr* storing the
+ /// bit-width.
+ ISK_BitWidthOrNothing = (unsigned) ICIS_NoInit,
+
+ /// The pointer is an (optional due to delayed parsing) Expr*
+ /// holding the copy-initializer.
+ ISK_InClassCopyInit = (unsigned) ICIS_CopyInit,
+
+ /// The pointer is an (optional due to delayed parsing) Expr*
+ /// holding the list-initializer.
+ ISK_InClassListInit = (unsigned) ICIS_ListInit,
+
+ /// The pointer is a VariableArrayType* that's been captured;
+ /// the enclosing context is a lambda or captured statement.
+ ISK_CapturedVLAType,
+ };
+
+ /// \brief Storage for either the bit-width, the in-class
+ /// initializer, or the captured variable length array bound.
///
- /// We can safely combine these two because in-class initializers are not
- /// permitted for bit-fields.
+ /// We can safely combine these because in-class initializers are
+ /// not permitted for bit-fields, and both are exclusive with VLA
+ /// captures.
///
- /// If the InClassInitStyle is not ICIS_NoInit and the initializer is null,
- /// then this field has an in-class initializer which has not yet been parsed
+ /// If the storage kind is ISK_InClassCopyInit or
+ /// ISK_InClassListInit, but the initializer is null, then this
+ /// field has an in-class initializer which has not yet been parsed
/// and attached.
- llvm::PointerIntPair<Expr *, 2, unsigned> InitializerOrBitWidth;
+ llvm::PointerIntPair<void *, 2, InitStorageKind> InitStorage;
protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
@@ -2172,7 +2209,7 @@ protected:
InClassInitStyle InitStyle)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
Mutable(Mutable), CachedFieldIndex(0),
- InitializerOrBitWidth(BW, InitStyle) {
+ InitStorage(BW, (InitStorageKind) InitStyle) {
assert((!BW || InitStyle == ICIS_NoInit) && "got initializer for bitfield");
}
@@ -2192,10 +2229,10 @@ public:
/// isMutable - Determines whether this field is mutable (C++ only).
bool isMutable() const { return Mutable; }
- /// isBitfield - Determines whether this field is a bitfield.
+ /// \brief Determines whether this field is a bitfield.
bool isBitField() const {
- return getInClassInitStyle() == ICIS_NoInit &&
- InitializerOrBitWidth.getPointer();
+ return InitStorage.getInt() == ISK_BitWidthOrNothing &&
+ InitStorage.getPointer() != nullptr;
}
/// @brief Determines whether this is an unnamed bitfield.
@@ -2208,24 +2245,34 @@ public:
bool isAnonymousStructOrUnion() const;
Expr *getBitWidth() const {
- return isBitField() ? InitializerOrBitWidth.getPointer() : nullptr;
+ return isBitField()
+ ? static_cast<Expr *>(InitStorage.getPointer())
+ : nullptr;
}
unsigned getBitWidthValue(const ASTContext &Ctx) const;
/// setBitWidth - Set the bit-field width for this member.
// Note: used by some clients (i.e., do not remove it).
- void setBitWidth(Expr *Width);
+ void setBitWidth(Expr *Width) {
+ assert(InitStorage.getInt() == ISK_BitWidthOrNothing &&
+ InitStorage.getPointer() == nullptr &&
+ "bit width, initializer or captured type already set");
+ InitStorage.setPointerAndInt(Width, ISK_BitWidthOrNothing);
+ }
+
/// removeBitWidth - Remove the bit-field width from this member.
// Note: used by some clients (i.e., do not remove it).
void removeBitWidth() {
assert(isBitField() && "no bitfield width to remove");
- InitializerOrBitWidth.setPointer(nullptr);
+ InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
}
/// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
/// this field has.
InClassInitStyle getInClassInitStyle() const {
- return static_cast<InClassInitStyle>(InitializerOrBitWidth.getInt());
+ InitStorageKind storageKind = InitStorage.getInt();
+ return (storageKind == ISK_CapturedVLAType
+ ? ICIS_NoInit : (InClassInitStyle) storageKind);
}
/// hasInClassInitializer - Determine whether this member has a C++11 in-class
@@ -2233,24 +2280,47 @@ public:
bool hasInClassInitializer() const {
return getInClassInitStyle() != ICIS_NoInit;
}
+
/// getInClassInitializer - Get the C++11 in-class initializer for this
/// member, or null if one has not been set. If a valid declaration has an
/// in-class initializer, but this returns null, then we have not parsed and
/// attached it yet.
Expr *getInClassInitializer() const {
- return hasInClassInitializer() ? InitializerOrBitWidth.getPointer()
- : nullptr;
+ return hasInClassInitializer()
+ ? static_cast<Expr *>(InitStorage.getPointer())
+ : nullptr;
}
+
/// setInClassInitializer - Set the C++11 in-class initializer for this
/// member.
- void setInClassInitializer(Expr *Init);
+ void setInClassInitializer(Expr *Init) {
+ assert(hasInClassInitializer() &&
+ InitStorage.getPointer() == nullptr &&
+ "bit width, initializer or captured type already set");
+ InitStorage.setPointer(Init);
+ }
+
/// removeInClassInitializer - Remove the C++11 in-class initializer from this
/// member.
void removeInClassInitializer() {
assert(hasInClassInitializer() && "no initializer to remove");
- InitializerOrBitWidth.setPointer(nullptr);
- InitializerOrBitWidth.setInt(ICIS_NoInit);
+ InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
+ }
+
+ /// \brief Determine whether this member captures the variable length array
+ /// type.
+ bool hasCapturedVLAType() const {
+ return InitStorage.getInt() == ISK_CapturedVLAType;
+ }
+
+ /// \brief Get the captured variable length array type.
+ const VariableArrayType *getCapturedVLAType() const {
+ return hasCapturedVLAType() ? static_cast<const VariableArrayType *>(
+ InitStorage.getPointer())
+ : nullptr;
}
+ /// \brief Set the captured variable length array type for this field.
+ void setCapturedVLAType(const VariableArrayType *VLAType);
/// getParent - Returns the parent of this field declaration, which
/// is the struct in which this method is defined.
@@ -2492,9 +2562,13 @@ public:
/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
/// alias-declaration.
class TypeAliasDecl : public TypedefNameDecl {
+ /// The template for which this is the pattern, if any.
+ TypeAliasTemplateDecl *Template;
+
TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo) {}
+ : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo),
+ Template(nullptr) {}
public:
static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2504,6 +2578,9 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
+ TypeAliasTemplateDecl *getDescribedAliasTemplate() const { return Template; }
+ void setDescribedAliasTemplate(TypeAliasTemplateDecl *TAT) { Template = TAT; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == TypeAlias; }
@@ -2647,7 +2724,7 @@ public:
}
/// isThisDeclarationADefinition() - Return true if this declaration
- /// is a completion definintion of the type. Provided for consistency.
+ /// is a completion definition of the type. Provided for consistency.
bool isThisDeclarationADefinition() const {
return isCompleteDefinition();
}
@@ -3136,6 +3213,17 @@ public:
/// \endcode
bool isInjectedClassName() const;
+ /// \brief Determine whether this record is a class describing a lambda
+ /// function object.
+ bool isLambda() const;
+
+ /// \brief Determine whether this record is a record for captured variables in
+ /// CapturedStmt construct.
+ bool isCapturedRecord() const;
+ /// \brief Mark the record as a record for captured variables in CapturedStmt
+ /// construct.
+ void setCapturedRecord();
+
/// getDefinition - Returns the RecordDecl that actually defines
/// this struct/union/class. When determining whether or not a
/// struct/union/class is completely defined, one should use this
@@ -3181,6 +3269,11 @@ public:
/// commandline option.
bool isMsStruct(const ASTContext &C) const;
+ /// \brief Whether we are allowed to insert extra padding between fields.
+ /// These padding are added to help AddressSanitizer detect
+ /// intra-object-overflow bugs.
+ bool mayInsertExtraPadding(bool EmitRemark = false) const;
+
private:
/// \brief Deserialize just the fields.
void LoadFieldsFromExternalStorage() const;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 607ca4ec27..984ab13df4 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -48,6 +48,7 @@ class ObjCInterfaceDecl;
class ObjCMethodDecl;
class ObjCProtocolDecl;
struct PrintingPolicy;
+class RecordDecl;
class Stmt;
class StoredDeclsMap;
class TranslationUnitDecl;
@@ -515,9 +516,13 @@ public:
/// indicating the declaration is used.
void markUsed(ASTContext &C);
- /// \brief Whether this declaration was referenced.
+ /// \brief Whether any declaration of this entity was referenced.
bool isReferenced() const;
+ /// \brief Whether this declaration was referenced. This should not be relied
+ /// upon for anything other than debugging.
+ bool isThisDeclarationReferenced() const { return Referenced; }
+
void setReferenced(bool R = true) { Referenced = R; }
/// \brief Whether this declaration is a top-level declaration (function,
@@ -675,9 +680,9 @@ public:
return const_cast<Decl*>(this)->getLexicalDeclContext();
}
- virtual bool isOutOfLine() const {
- return getLexicalDeclContext() != getDeclContext();
- }
+ /// Determine whether this declaration is declared out of line (outside its
+ /// semantic context).
+ virtual bool isOutOfLine() const;
/// setDeclContext - Set both the semantic and lexical DeclContext
/// to DC.
@@ -1234,6 +1239,12 @@ public:
return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
}
+ /// \brief Retrieve the outermost lexically enclosing record context.
+ RecordDecl *getOuterLexicalRecordContext();
+ const RecordDecl *getOuterLexicalRecordContext() const {
+ return const_cast<DeclContext *>(this)->getOuterLexicalRecordContext();
+ }
+
/// \brief Test if this context is part of the enclosing namespace set of
/// the context NS, as defined in C++0x [namespace.def]p9. If either context
/// isn't a namespace, this is equivalent to Equals().
@@ -1642,7 +1653,7 @@ public:
void dumpDeclContext() const;
void dumpLookups() const;
- void dumpLookups(llvm::raw_ostream &OS) const;
+ void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false) const;
private:
void reconcileExternalVisibleStorage() const;
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 72fad7c28e..062c1527d7 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -538,6 +538,12 @@ class CXXRecordDecl : public RecordDecl {
ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
MethodTyInfo(Info) {
IsLambda = true;
+
+ // C++11 [expr.prim.lambda]p3:
+ // This class type is neither an aggregate nor a literal type.
+ Aggregate = false;
+ PlainOldData = false;
+ HasNonLiteralTypeFieldsOrBases = true;
}
/// \brief Whether this lambda is known to be dependent, even if its
@@ -1371,6 +1377,15 @@ public:
/// \brief Set the kind of specialization or template instantiation this is.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+ /// \brief Retrieve the record declaration from which this record could be
+ /// instantiated. Returns null if this class is not a template instantiation.
+ const CXXRecordDecl *getTemplateInstantiationPattern() const;
+
+ CXXRecordDecl *getTemplateInstantiationPattern() {
+ return const_cast<CXXRecordDecl *>(const_cast<const CXXRecordDecl *>(this)
+ ->getTemplateInstantiationPattern());
+ }
+
/// \brief Returns the destructor decl for this class.
CXXDestructorDecl *getDestructor() const;
@@ -2104,8 +2119,8 @@ public:
}
ArrayRef<VarDecl *> getArrayIndexes() {
assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
- return ArrayRef<VarDecl *>(reinterpret_cast<VarDecl **>(this + 1),
- getNumArrayIndices());
+ return llvm::makeArrayRef(reinterpret_cast<VarDecl **>(this + 1),
+ getNumArrayIndices());
}
/// \brief Get the initializer.
@@ -2636,7 +2651,8 @@ public:
/// \code
/// namespace Foo = Bar;
/// \endcode
-class NamespaceAliasDecl : public NamedDecl {
+class NamespaceAliasDecl : public NamedDecl,
+ public Redeclarable<NamespaceAliasDecl> {
void anchor() override;
/// \brief The location of the \c namespace keyword.
@@ -2654,17 +2670,47 @@ class NamespaceAliasDecl : public NamedDecl {
/// a NamespaceAliasDecl.
NamedDecl *Namespace;
- NamespaceAliasDecl(DeclContext *DC, SourceLocation NamespaceLoc,
- SourceLocation AliasLoc, IdentifierInfo *Alias,
- NestedNameSpecifierLoc QualifierLoc,
+ NamespaceAliasDecl(ASTContext &C, DeclContext *DC,
+ SourceLocation NamespaceLoc, SourceLocation AliasLoc,
+ IdentifierInfo *Alias, NestedNameSpecifierLoc QualifierLoc,
SourceLocation IdentLoc, NamedDecl *Namespace)
- : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias),
- NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
- QualifierLoc(QualifierLoc), Namespace(Namespace) { }
+ : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias), redeclarable_base(C),
+ NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
+ QualifierLoc(QualifierLoc), Namespace(Namespace) {}
+
+ typedef Redeclarable<NamespaceAliasDecl> redeclarable_base;
+ NamespaceAliasDecl *getNextRedeclarationImpl() override;
+ NamespaceAliasDecl *getPreviousDeclImpl() override;
+ NamespaceAliasDecl *getMostRecentDeclImpl() override;
friend class ASTDeclReader;
public:
+ static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation NamespaceLoc,
+ SourceLocation AliasLoc,
+ IdentifierInfo *Alias,
+ NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation IdentLoc,
+ NamedDecl *Namespace);
+
+ static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ typedef redeclarable_base::redecl_range redecl_range;
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
+ using redeclarable_base::getPreviousDecl;
+ using redeclarable_base::getMostRecentDecl;
+
+ NamespaceAliasDecl *getCanonicalDecl() override {
+ return getFirstDecl();
+ }
+ const NamespaceAliasDecl *getCanonicalDecl() const {
+ return getFirstDecl();
+ }
+
/// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace, with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
@@ -2701,16 +2747,6 @@ public:
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *getAliasedNamespace() const { return Namespace; }
- static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation NamespaceLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Namespace);
-
- static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(NamespaceLoc, IdentLoc);
}
@@ -2824,7 +2860,7 @@ public:
/// \code
/// using someNameSpace::someIdentifier;
/// \endcode
-class UsingDecl : public NamedDecl {
+class UsingDecl : public NamedDecl, public Mergeable<UsingDecl> {
void anchor() override;
/// \brief The source location of the 'using' keyword itself.
@@ -2948,6 +2984,10 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
+ /// Retrieves the canonical declaration of this declaration.
+ UsingDecl *getCanonicalDecl() override { return getFirstDecl(); }
+ const UsingDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Using; }
@@ -2966,7 +3006,8 @@ public:
/// using Base<T>::foo;
/// };
/// \endcode
-class UnresolvedUsingValueDecl : public ValueDecl {
+class UnresolvedUsingValueDecl : public ValueDecl,
+ public Mergeable<UnresolvedUsingValueDecl> {
void anchor() override;
/// \brief The source location of the 'using' keyword
@@ -3022,6 +3063,14 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
+ /// Retrieves the canonical declaration of this declaration.
+ UnresolvedUsingValueDecl *getCanonicalDecl() override {
+ return getFirstDecl();
+ }
+ const UnresolvedUsingValueDecl *getCanonicalDecl() const {
+ return getFirstDecl();
+ }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
@@ -3040,7 +3089,9 @@ public:
///
/// The type associated with an unresolved using typename decl is
/// currently always a typename type.
-class UnresolvedUsingTypenameDecl : public TypeDecl {
+class UnresolvedUsingTypenameDecl
+ : public TypeDecl,
+ public Mergeable<UnresolvedUsingTypenameDecl> {
void anchor() override;
/// \brief The source location of the 'typename' keyword
@@ -3084,6 +3135,14 @@ public:
static UnresolvedUsingTypenameDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
+ /// Retrieves the canonical declaration of this declaration.
+ UnresolvedUsingTypenameDecl *getCanonicalDecl() override {
+ return getFirstDecl();
+ }
+ const UnresolvedUsingTypenameDecl *getCanonicalDecl() const {
+ return getFirstDecl();
+ }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
};
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 97741c1c37..12b93b408a 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -135,8 +135,12 @@ public:
/// Retrieves the source range for the friend declaration.
SourceRange getSourceRange() const override LLVM_READONLY {
if (NamedDecl *ND = getFriendDecl()) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+ return FD->getSourceRange();
if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
return FTD->getSourceRange();
+ if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
+ return CTD->getSourceRange();
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
if (DD->getOuterLocStart() != DD->getInnerLocStart())
return DD->getSourceRange();
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 520f523a6d..55d4b0f169 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -329,6 +329,7 @@ public:
QualType getReturnType() const { return MethodDeclType; }
void setReturnType(QualType T) { MethodDeclType = T; }
+ SourceRange getReturnTypeSourceRange() const;
/// \brief Determine the type of an expression that sends a message to this
/// function.
@@ -378,8 +379,7 @@ public:
/// ignored.
void setMethodParams(ASTContext &C,
ArrayRef<ParmVarDecl*> Params,
- ArrayRef<SourceLocation> SelLocs =
- ArrayRef<SourceLocation>());
+ ArrayRef<SourceLocation> SelLocs = llvm::None);
// Iterator access to parameter types.
typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
@@ -591,7 +591,8 @@ public:
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
- ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
+ ObjCPropertyDecl *
+ FindPropertyDeclaration(const IdentifierInfo *PropertyId) const;
typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
@@ -956,6 +957,10 @@ public:
unsigned Num,
ASTContext &C);
+ /// Produce a name to be used for class's metadata. It comes either via
+ /// objc_runtime_name attribute or class name.
+ StringRef getObjCRuntimeNameAsString() const;
+
/// Returns the designated initializers for the interface.
///
/// If this declaration does not have methods marked as designated
@@ -1653,6 +1658,10 @@ public:
/// \brief Starts the definition of this Objective-C protocol.
void startDefinition();
+ /// Produce a name to be used for protocol's metadata. It comes either via
+ /// objc_runtime_name attribute or protocol name.
+ StringRef getObjCRuntimeNameAsString() const;
+
SourceRange getSourceRange() const override LLVM_READONLY {
if (isThisDeclarationADefinition())
return ObjCContainerDecl::getSourceRange();
@@ -2100,6 +2109,10 @@ public:
std::string getNameAsString() const {
return getName();
}
+
+ /// Produce a name to be used for class's metadata. It comes either via
+ /// class's objc_runtime_name attribute or class name.
+ StringRef getObjCRuntimeNameAsString() const;
const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
@@ -2342,7 +2355,7 @@ public:
/// Lookup a property by name in the specified DeclContext.
static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
- IdentifierInfo *propertyID);
+ const IdentifierInfo *propertyID);
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCProperty; }
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 1b329dcd00..7f0616f1e6 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -12,13 +12,14 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_OPENMP_H
-#define LLVM_CLANG_AST_OPENMP_H
+#ifndef LLVM_CLANG_AST_DECLOPENMP_H
+#define LLVM_CLANG_AST_DECLOPENMP_H
#include "clang/AST/DeclBase.h"
#include "llvm/ADT/ArrayRef.h"
namespace clang {
+class Expr;
/// \brief This represents '#pragma omp threadprivate ...' directive.
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
@@ -42,9 +43,8 @@ class OMPThreadPrivateDecl : public Decl {
Decl(DK, DC, L), NumVars(0) { }
ArrayRef<const Expr *> getVars() const {
- return ArrayRef<const Expr *>(
- reinterpret_cast<const Expr * const *>(this + 1),
- NumVars);
+ return llvm::makeArrayRef(reinterpret_cast<const Expr * const *>(this + 1),
+ NumVars);
}
MutableArrayRef<Expr *> getVars() {
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 980a06e35b..9283d2dc43 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -87,10 +87,10 @@ public:
unsigned size() const { return NumParams; }
ArrayRef<NamedDecl*> asArray() {
- return ArrayRef<NamedDecl*>(begin(), size());
+ return llvm::makeArrayRef(begin(), end());
}
ArrayRef<const NamedDecl*> asArray() const {
- return ArrayRef<const NamedDecl*>(begin(), size());
+ return llvm::makeArrayRef(begin(), size());
}
NamedDecl* getParam(unsigned Idx) {
@@ -204,7 +204,7 @@ public:
/// \brief Produce this as an array ref.
ArrayRef<TemplateArgument> asArray() const {
- return ArrayRef<TemplateArgument>(data(), size());
+ return llvm::makeArrayRef(data(), size());
}
/// \brief Retrieve the number of template arguments in this
@@ -236,7 +236,7 @@ protected:
TemplateParams(nullptr) {}
// Construct a template decl with the given name and parameters.
- // Used when there is not templated element (tt-params, alias?).
+ // Used when there is not templated element (tt-params).
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params)
: NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 3076b30cd3..49e51e09b8 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -59,6 +59,7 @@ public:
CXXLiteralOperatorName,
CXXUsingDirective
};
+ static const unsigned NumNameKinds = CXXUsingDirective + 1;
private:
/// StoredNameKind - The kind of name that is actually stored in the
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
index 63047ec4db..63066797b3 100644
--- a/include/clang/AST/DependentDiagnostic.h
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
-#define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
+#ifndef LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
+#define LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclContextInternals.h"
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index e208280ccc..d94e225c74 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -45,6 +45,7 @@ namespace clang {
class ObjCPropertyRefExpr;
class OpaqueValueExpr;
class ParmVarDecl;
+ class StringLiteral;
class TargetInfo;
class ValueDecl;
@@ -124,8 +125,7 @@ public:
QualType getType() const { return TR; }
void setType(QualType t) {
// In C++, the type of an expression is always adjusted so that it
- // will not have reference type an expression will never have
- // reference type (C++ [expr]p6). Use
+ // will not have reference type (C++ [expr]p6). Use
// QualType::getNonReferenceType() to retrieve the non-reference
// type. Additionally, inspect Expr::isLvalue to determine whether
// an expression that is adjusted in this manner should be
@@ -1161,7 +1161,7 @@ public:
friend class ASTStmtWriter;
};
-/// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
+/// \brief [C99 6.4.2.2] - A predefined identifier such as __func__.
class PredefinedExpr : public Expr {
public:
enum IdentType {
@@ -1171,7 +1171,7 @@ public:
FuncDName,
FuncSig,
PrettyFunction,
- /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
+ /// \brief The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
PrettyFunctionNoVirtual
};
@@ -1179,24 +1179,27 @@ public:
private:
SourceLocation Loc;
IdentType Type;
+ Stmt *FnName;
+
public:
- PredefinedExpr(SourceLocation l, QualType type, IdentType IT)
- : Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary,
- type->isDependentType(), type->isDependentType(),
- type->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Loc(l), Type(IT) {}
+ PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT,
+ StringLiteral *SL);
/// \brief Construct an empty predefined expression.
explicit PredefinedExpr(EmptyShell Empty)
- : Expr(PredefinedExprClass, Empty) { }
+ : Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FnName(nullptr) {}
IdentType getIdentType() const { return Type; }
- void setIdentType(IdentType IT) { Type = IT; }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
+ StringLiteral *getFunctionName();
+ const StringLiteral *getFunctionName() const {
+ return const_cast<PredefinedExpr *>(this)->getFunctionName();
+ }
+
+ static StringRef getIdentTypeName(IdentType IT);
static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
@@ -1207,7 +1210,9 @@ public:
}
// Iterators
- child_range children() { return child_range(); }
+ child_range children() { return child_range(&FnName, &FnName + 1); }
+
+ friend class ASTStmtReader;
};
/// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without
@@ -2212,11 +2217,11 @@ public:
/// getArg - Return the specified argument.
Expr *getArg(unsigned Arg) {
assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(SubExprs[Arg+getNumPreArgs()+PREARGS_START]);
+ return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
}
const Expr *getArg(unsigned Arg) const {
assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(SubExprs[Arg+getNumPreArgs()+PREARGS_START]);
+ return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
}
/// setArg - Set the specified argument.
@@ -2256,8 +2261,8 @@ public:
/// interface. This provides efficient reverse iteration of the
/// subexpressions. This is currently used for CFG construction.
ArrayRef<Stmt*> getRawSubExprs() {
- return ArrayRef<Stmt*>(SubExprs,
- getNumPreArgs() + PREARGS_START + getNumArgs());
+ return llvm::makeArrayRef(SubExprs,
+ getNumPreArgs() + PREARGS_START + getNumArgs());
}
/// getNumCommas - Return the number of commas that must have been present in
@@ -2653,9 +2658,6 @@ public:
/// representation in the source code (ExplicitCastExpr's derived
/// classes).
class CastExpr : public Expr {
-public:
- typedef clang::CastKind CastKind;
-
private:
Stmt *Op;
@@ -2673,20 +2675,23 @@ private:
}
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())),
- (ty->containsUnexpandedParameterPack() ||
- (op && op->containsUnexpandedParameterPack()))),
- Op(op) {
+ 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) {
assert(kind != CK_Invalid && "creating cast with invalid cast kind");
CastExprBits.Kind = kind;
setBasePathSize(BasePathSize);
@@ -4167,6 +4172,17 @@ public:
return Designators + NumDesignators;
}
+ typedef llvm::iterator_range<designators_iterator> designators_range;
+ designators_range designators() {
+ return designators_range(designators_begin(), designators_end());
+ }
+
+ typedef llvm::iterator_range<const_designators_iterator>
+ designators_const_range;
+ designators_const_range designators() const {
+ return designators_const_range(designators_begin(), designators_end());
+ }
+
typedef std::reverse_iterator<designators_iterator>
reverse_designators_iterator;
reverse_designators_iterator designators_rbegin() {
@@ -4830,6 +4846,24 @@ public:
return child_range(SubExprs, SubExprs+NumSubExprs);
}
};
+
+/// TypoExpr - Internal placeholder for expressions where typo correction
+/// still needs to be performed and/or an error diagnostic emitted.
+class TypoExpr : public Expr {
+public:
+ TypoExpr(QualType T)
+ : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary,
+ /*isTypeDependent*/ true,
+ /*isValueDependent*/ true,
+ /*isInstantiationDependent*/ true,
+ /*containsUnexpandedParameterPack*/ false) {
+ assert(T->isDependentType() && "TypoExpr given a non-dependent type");
+ }
+
+ child_range children() { return child_range(); }
+ SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+};
} // end namespace clang
#endif
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 4403b0858f..040fbe7f92 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -737,8 +737,8 @@ public:
/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
/// a single GUID.
- static UuidAttr *GetUuidAttrOfType(QualType QT,
- bool *HasMultipleGUIDsPtr = nullptr);
+ static const UuidAttr *GetUuidAttrOfType(QualType QT,
+ bool *HasMultipleGUIDsPtr = nullptr);
// Iterators
child_range children() {
@@ -967,8 +967,14 @@ public:
const FieldDecl *getField() const { return Field; }
/// \brief Get the initialization expression that will be used.
- const Expr *getExpr() const { return Field->getInClassInitializer(); }
- Expr *getExpr() { return Field->getInClassInitializer(); }
+ const Expr *getExpr() const {
+ assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
+ return Field->getInClassInitializer();
+ }
+ Expr *getExpr() {
+ assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
+ return Field->getInClassInitializer();
+ }
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
@@ -1077,6 +1083,7 @@ private:
bool Elidable : 1;
bool HadMultipleCandidates : 1;
bool ListInitialization : 1;
+ bool StdInitListInitialization : 1;
bool ZeroInitialization : 1;
unsigned ConstructKind : 2;
Stmt **Args;
@@ -1088,6 +1095,7 @@ protected:
ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
@@ -1114,6 +1122,7 @@ public:
ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
@@ -1137,6 +1146,13 @@ public:
bool isListInitialization() const { return ListInitialization; }
void setListInitialization(bool V) { ListInitialization = V; }
+ /// \brief Whether this constructor call was written as list-initialization,
+ /// but was interpreted as forming a std::initializer_list<T> from the list
+ /// and passing that as a single constructor argument.
+ /// See C++11 [over.match.list]p1 bullet 1.
+ bool isStdInitListInitialization() const { return StdInitListInitialization; }
+ void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
+
/// \brief Whether this construction first requires
/// zero-initialization before the initializer is called.
bool requiresZeroInitialization() const { return ZeroInitialization; }
@@ -1155,6 +1171,13 @@ public:
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
+ typedef llvm::iterator_range<arg_iterator> arg_range;
+ typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+
+ arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
+ arg_const_range arguments() const {
+ return arg_const_range(arg_begin(), arg_end());
+ }
arg_iterator arg_begin() { return Args; }
arg_iterator arg_end() { return Args + NumArgs; }
@@ -1272,6 +1295,7 @@ public:
SourceRange ParenOrBraceRange,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization);
explicit CXXTemporaryObjectExpr(EmptyShell Empty)
: CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
@@ -1468,6 +1492,12 @@ public:
/// arguments.
typedef Expr **capture_init_iterator;
+ /// \brief Retrieve the initialization expressions for this lambda's captures.
+ llvm::iterator_range<capture_init_iterator> capture_inits() const {
+ return llvm::iterator_range<capture_init_iterator>(capture_init_begin(),
+ capture_init_end());
+ }
+
/// \brief Retrieve the first initialization argument for this
/// lambda expression (which initializes the first capture field).
capture_init_iterator capture_init_begin() const {
@@ -1552,12 +1582,12 @@ class CXXScalarValueInitExpr : public Expr {
public:
/// \brief Create an explicitly-written scalar-value initialization
/// expression.
- CXXScalarValueInitExpr(QualType Type,
- TypeSourceInfo *TypeInfo,
- SourceLocation rParenLoc ) :
- Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
- false, false, Type->isInstantiationDependentType(), false),
- RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
+ CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
+ SourceLocation rParenLoc)
+ : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
+ false, false, Type->isInstantiationDependentType(),
+ Type->containsUnexpandedParameterPack()),
+ RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
explicit CXXScalarValueInitExpr(EmptyShell Shell)
: Expr(CXXScalarValueInitExprClass, Shell) { }
@@ -2096,7 +2126,7 @@ public:
/// \brief Retrieve the argument types.
ArrayRef<TypeSourceInfo *> getArgs() const {
- return ArrayRef<TypeSourceInfo *>(getTypeSourceInfos(), getNumArgs());
+ return llvm::makeArrayRef(getTypeSourceInfos(), getNumArgs());
}
typedef TypeSourceInfo **arg_iterator;
@@ -2750,7 +2780,7 @@ public:
ArrayRef<CleanupObject> objects);
ArrayRef<CleanupObject> getObjects() const {
- return ArrayRef<CleanupObject>(getObjectsBuffer(), getNumObjects());
+ return llvm::makeArrayRef(getObjectsBuffer(), getNumObjects());
}
unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
@@ -3794,6 +3824,69 @@ public:
}
};
+/// \brief Represents a folding of a pack over an operator.
+///
+/// This expression is always dependent and represents a pack expansion of the
+/// forms:
+///
+/// ( expr op ... )
+/// ( ... op expr )
+/// ( expr op ... op expr )
+class CXXFoldExpr : public Expr {
+ SourceLocation LParenLoc;
+ SourceLocation EllipsisLoc;
+ SourceLocation RParenLoc;
+ Stmt *SubExprs[2];
+ BinaryOperatorKind Opcode;
+
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+public:
+ CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS,
+ BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS,
+ SourceLocation RParenLoc)
+ : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary,
+ /*Dependent*/ true, true, true,
+ /*ContainsUnexpandedParameterPack*/ false),
+ LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
+ Opcode(Opcode) {
+ SubExprs[0] = LHS;
+ SubExprs[1] = RHS;
+ }
+ CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
+
+ Expr *getLHS() const { return static_cast<Expr*>(SubExprs[0]); }
+ Expr *getRHS() const { return static_cast<Expr*>(SubExprs[1]); }
+
+ /// Does this produce a right-associated sequence of operators?
+ bool isRightFold() const {
+ return getLHS() && getLHS()->containsUnexpandedParameterPack();
+ }
+ /// Does this produce a left-associated sequence of operators?
+ bool isLeftFold() const { return !isRightFold(); }
+ /// Get the pattern, that is, the operand that contains an unexpanded pack.
+ Expr *getPattern() const { return isLeftFold() ? getRHS() : getLHS(); }
+ /// Get the operand that doesn't contain a pack, for a binary fold.
+ Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); }
+
+ SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+ BinaryOperatorKind getOperator() const { return Opcode; }
+
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return LParenLoc;
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return RParenLoc;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXFoldExprClass;
+ }
+
+ // Iterators
+ child_range children() { return child_range(SubExprs, SubExprs + 2); }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 1e8eff38d3..ff1d180ee8 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -11,8 +11,8 @@
// construction of AST nodes from some external source.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
-#define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
+#ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
+#define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclBase.h"
@@ -650,4 +650,4 @@ typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
} // end namespace clang
-#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
+#endif
diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h
index 8633c97965..a7468a0fd5 100644
--- a/include/clang/AST/LambdaCapture.h
+++ b/include/clang/AST/LambdaCapture.h
@@ -68,13 +68,23 @@ public:
/// \brief Determine whether this capture handles the C++ \c this
/// pointer.
- bool capturesThis() const { return DeclAndBits.getPointer() == nullptr; }
+ bool capturesThis() const {
+ return (DeclAndBits.getPointer() == nullptr) &&
+ !(DeclAndBits.getInt() & Capture_ByCopy);
+ }
/// \brief Determine whether this capture handles a variable.
bool capturesVariable() const {
return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
}
+ /// \brief Determine whether this captures a variable length array bound
+ /// expression.
+ bool capturesVLAType() const {
+ return (DeclAndBits.getPointer() == nullptr) &&
+ (DeclAndBits.getInt() & Capture_ByCopy);
+ }
+
/// \brief Determine whether this is an init-capture.
bool isInitCapture() const {
return capturesVariable() && getCapturedVar()->isInitCapture();
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index a8d119971b..cbe08a1a76 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -156,6 +156,11 @@ public:
virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
raw_ostream &) = 0;
+ virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
+ raw_ostream &) = 0;
+ virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
+ raw_ostream &) = 0;
+
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Itanium;
}
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
index 56c995264b..7a818557fd 100644
--- a/include/clang/AST/MangleNumberingContext.h
+++ b/include/clang/AST/MangleNumberingContext.h
@@ -12,8 +12,8 @@
// literals.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_MANGLENUMBERINGCONTEXT_H
-#define LLVM_CLANG_MANGLENUMBERINGCONTEXT_H
+#ifndef LLVM_CLANG_AST_MANGLENUMBERINGCONTEXT_H
+#define LLVM_CLANG_AST_MANGLENUMBERINGCONTEXT_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
@@ -30,23 +30,20 @@ class VarDecl;
/// \brief Keeps track of the mangled names of lambda expressions and block
/// literals within a particular context.
-class MangleNumberingContext
- : public RefCountedBase<MangleNumberingContext> {
- llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
-
+class MangleNumberingContext : public RefCountedBase<MangleNumberingContext> {
public:
virtual ~MangleNumberingContext() {}
/// \brief Retrieve the mangling number of a new lambda expression with the
/// given call operator within this context.
- unsigned getManglingNumber(const CXXMethodDecl *CallOperator);
+ virtual unsigned getManglingNumber(const CXXMethodDecl *CallOperator) = 0;
/// \brief Retrieve the mangling number of a new block literal within this
/// context.
- unsigned getManglingNumber(const BlockDecl *BD);
+ virtual unsigned getManglingNumber(const BlockDecl *BD) = 0;
/// Static locals are numbered by source order.
- unsigned getStaticLocalNumber(const VarDecl *VD);
+ virtual unsigned getStaticLocalNumber(const VarDecl *VD) = 0;
/// \brief Retrieve the mangling number of a static local variable within
/// this context.
@@ -58,6 +55,6 @@ public:
virtual unsigned getManglingNumber(const TagDecl *TD,
unsigned MSLocalManglingNumber) = 0;
};
-
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
index 0b21b03348..33fcce2109 100644
--- a/include/clang/AST/NSAPI.h
+++ b/include/clang/AST/NSAPI.h
@@ -42,7 +42,8 @@ public:
NSStr_stringWithUTF8String,
NSStr_stringWithCStringEncoding,
NSStr_stringWithCString,
- NSStr_initWithString
+ NSStr_initWithString,
+ NSStr_initWithUTF8String
};
static const unsigned NumNSStringMethods = 5;
@@ -100,8 +101,8 @@ public:
NSDict_objectForKey,
NSMutableDict_setObjectForKey
};
- static const unsigned NumNSDictionaryMethods = 11;
-
+ static const unsigned NumNSDictionaryMethods = 12;
+
/// \brief The Objective-C NSDictionary selectors.
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
@@ -184,6 +185,9 @@ public:
bool isObjCNSIntegerType(QualType T) const;
/// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
bool isObjCNSUIntegerType(QualType T) const;
+ /// \brief Returns one of NSIntegral typedef names if \param T is a typedef
+ /// of that name in objective-c.
+ StringRef GetNSIntegralKind(QualType T) const;
private:
bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index fc719bdc16..518f1232fe 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -22,6 +22,7 @@
namespace clang {
class ASTContext;
+class CXXRecordDecl;
class NamespaceAliasDecl;
class NamespaceDecl;
class IdentifierInfo;
@@ -45,7 +46,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
/// \brief Enumeration describing
enum StoredSpecifierKind {
StoredIdentifier = 0,
- StoredNamespaceOrAlias = 1,
+ StoredDecl = 1,
StoredTypeSpec = 2,
StoredTypeSpecWithTemplate = 3
};
@@ -83,7 +84,10 @@ public:
/// stored as a Type*.
TypeSpecWithTemplate,
/// \brief The global specifier '::'. There is no stored value.
- Global
+ Global,
+ /// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
+ /// the class it appeared in.
+ Super
};
private:
@@ -143,6 +147,11 @@ public:
/// scope.
static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
+ /// \brief Returns the nested name specifier representing the __super scope
+ /// for the given CXXRecordDecl.
+ static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
+ CXXRecordDecl *RD);
+
/// \brief Return the prefix of this nested name specifier.
///
/// The prefix contains all of the parts of the nested name
@@ -172,6 +181,10 @@ public:
/// specifier.
NamespaceAliasDecl *getAsNamespaceAlias() const;
+ /// \brief Retrieve the record declaration stored in this nested name
+ /// specifier.
+ CXXRecordDecl *getAsRecordDecl() const;
+
/// \brief Retrieve the type stored in this nested name specifier.
const Type *getAsType() const {
if (Prefix.getInt() == StoredTypeSpec ||
@@ -421,7 +434,22 @@ public:
/// \brief Turn this (empty) nested-name-specifier into the global
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
-
+
+ /// \brief Turns this (empty) nested-name-specifier into '__super'
+ /// nested-name-specifier.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param RD The declaration of the class in which nested-name-specifier
+ /// appeared.
+ ///
+ /// \param SuperLoc The location of the '__super' keyword.
+ /// name.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
+ SourceLocation SuperLoc, SourceLocation ColonColonLoc);
/// \brief Make a new nested-name-specifier from incomplete source-location
/// information.
///
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index 95cb11ce64..0c3002c103 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -61,7 +61,7 @@ public:
ConstStmtRange children() const {
return const_cast<OMPClause *>(this)->children();
}
- static bool classof(const OMPClause *T) { return true; }
+ static bool classof(const OMPClause *) { return true; }
};
/// \brief This represents clauses with the list of variables like 'private',
@@ -135,10 +135,10 @@ public:
/// \brief Fetches list of all variables in the clause.
ArrayRef<const Expr *> getVarRefs() const {
- return ArrayRef<const Expr *>(
+ return llvm::makeArrayRef(
reinterpret_cast<const Expr *const *>(
reinterpret_cast<const char *>(this) +
- llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
+ llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<const Expr *>())),
NumVars);
}
};
@@ -196,6 +196,59 @@ public:
StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
};
+/// \brief This represents 'final' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp task final(a > 5)
+/// \endcode
+/// In this example directive '#pragma omp task' has simple 'final'
+/// clause with condition 'a > 5'.
+///
+class OMPFinalClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Condition of the 'if' clause.
+ Stmt *Condition;
+
+ /// \brief Set condition.
+ ///
+ void setCondition(Expr *Cond) { Condition = Cond; }
+
+public:
+ /// \brief Build 'final' clause with condition \a Cond.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param Cond Condition of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPFinalClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_final, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Condition(Cond) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPFinalClause()
+ : OMPClause(OMPC_final, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Condition(nullptr) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns condition.
+ Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_final;
+ }
+
+ StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
+};
+
/// \brief This represents 'num_threads' clause in the '#pragma omp ...'
/// directive.
///
@@ -658,6 +711,212 @@ public:
StmtRange children() { return StmtRange(); }
};
+/// \brief This represents 'untied' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp task untied
+/// \endcode
+/// In this example directive '#pragma omp task' has 'untied' clause.
+///
+class OMPUntiedClause : public OMPClause {
+public:
+ /// \brief Build 'untied' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_untied, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPUntiedClause()
+ : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_untied;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'mergeable' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp task mergeable
+/// \endcode
+/// In this example directive '#pragma omp task' has 'mergeable' clause.
+///
+class OMPMergeableClause : public OMPClause {
+public:
+ /// \brief Build 'mergeable' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPMergeableClause()
+ : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_mergeable;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'read' clause in the '#pragma omp atomic' directive.
+///
+/// \code
+/// #pragma omp atomic read
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'read' clause.
+///
+class OMPReadClause : public OMPClause {
+public:
+ /// \brief Build 'read' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_read, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_read;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'write' clause in the '#pragma omp atomic' directive.
+///
+/// \code
+/// #pragma omp atomic write
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'write' clause.
+///
+class OMPWriteClause : public OMPClause {
+public:
+ /// \brief Build 'write' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_write, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPWriteClause()
+ : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_write;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'update' clause in the '#pragma omp atomic'
+/// directive.
+///
+/// \code
+/// #pragma omp atomic update
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'update' clause.
+///
+class OMPUpdateClause : public OMPClause {
+public:
+ /// \brief 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) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPUpdateClause()
+ : OMPClause(OMPC_update, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_update;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'capture' clause in the '#pragma omp atomic'
+/// directive.
+///
+/// \code
+/// #pragma omp atomic capture
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'capture' clause.
+///
+class OMPCaptureClause : public OMPClause {
+public:
+ /// \brief Build 'capture' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_capture, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPCaptureClause()
+ : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_capture;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'seq_cst' clause in the '#pragma omp atomic'
+/// directive.
+///
+/// \code
+/// #pragma omp atomic seq_cst
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'seq_cst' clause.
+///
+class OMPSeqCstClause : public OMPClause {
+public:
+ /// \brief Build 'seq_cst' clause.
+ ///
+ /// \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) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPSeqCstClause()
+ : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_seq_cst;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
///
/// \code
@@ -667,6 +926,7 @@ public:
/// with the variables 'a' and 'b'.
///
class OMPPrivateClause : public OMPVarListClause<OMPPrivateClause> {
+ friend class OMPClauseReader;
/// \brief Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
@@ -688,6 +948,20 @@ class OMPPrivateClause : public OMPVarListClause<OMPPrivateClause> {
SourceLocation(), SourceLocation(),
N) {}
+ /// \brief Sets the list of references to private copies with initializers for
+ /// new private variables.
+ /// \param VL List of references.
+ void setPrivateCopies(ArrayRef<Expr *> VL);
+
+ /// \brief Gets the list of references to private copies with initializers for
+ /// new private variables.
+ MutableArrayRef<Expr *> getPrivateCopies() {
+ return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getPrivateCopies() const {
+ return llvm::makeArrayRef(varlist_end(), varlist_size());
+ }
+
public:
/// \brief Creates clause with a list of variables \a VL.
///
@@ -696,10 +970,12 @@ public:
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
+ /// \param PrivateVL List of references to private copies with initializers.
///
static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ SourceLocation EndLoc, ArrayRef<Expr *> VL,
+ ArrayRef<Expr *> PrivateVL);
/// \brief Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
@@ -707,6 +983,21 @@ public:
///
static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+ typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
+ typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
+ typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
+ typedef llvm::iterator_range<private_copies_const_iterator>
+ private_copies_const_range;
+
+ private_copies_range private_copies() {
+ return private_copies_range(getPrivateCopies().begin(),
+ getPrivateCopies().end());
+ }
+ private_copies_const_range private_copies() const {
+ return private_copies_const_range(getPrivateCopies().begin(),
+ getPrivateCopies().end());
+ }
+
StmtRange children() {
return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
@@ -727,6 +1018,8 @@ public:
/// with the variables 'a' and 'b'.
///
class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
+ friend class OMPClauseReader;
+
/// \brief Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
@@ -747,6 +1040,33 @@ class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
: OMPVarListClause<OMPFirstprivateClause>(
OMPC_firstprivate, SourceLocation(), SourceLocation(),
SourceLocation(), N) {}
+ /// \brief Sets the list of references to private copies with initializers for
+ /// new private variables.
+ /// \param VL List of references.
+ void setPrivateCopies(ArrayRef<Expr *> VL);
+
+ /// \brief Gets the list of references to private copies with initializers for
+ /// new private variables.
+ MutableArrayRef<Expr *> getPrivateCopies() {
+ return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getPrivateCopies() const {
+ return llvm::makeArrayRef(varlist_end(), varlist_size());
+ }
+
+ /// \brief Sets the list of references to initializer variables for new
+ /// private variables.
+ /// \param VL List of references.
+ void setInits(ArrayRef<Expr *> VL);
+
+ /// \brief Gets the list of references to initializer variables for new
+ /// private variables.
+ MutableArrayRef<Expr *> getInits() {
+ return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getInits() const {
+ return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
+ }
public:
/// \brief Creates clause with a list of variables \a VL.
@@ -755,11 +1075,16 @@ public:
/// \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 variables.
+ /// \param VL List of references to the original variables.
+ /// \param PrivateVL List of references to private copies with initializers.
+ /// \param InitVL List of references to auto generated variables used for
+ /// initialization of a single array element. Used if firstprivate variable is
+ /// of array type.
///
static OMPFirstprivateClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
+ ArrayRef<Expr *> InitVL);
/// \brief Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
@@ -767,6 +1092,33 @@ public:
///
static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+ typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
+ typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
+ typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
+ typedef llvm::iterator_range<private_copies_const_iterator>
+ private_copies_const_range;
+
+ private_copies_range private_copies() {
+ return private_copies_range(getPrivateCopies().begin(),
+ getPrivateCopies().end());
+ }
+ private_copies_const_range private_copies() const {
+ return private_copies_const_range(getPrivateCopies().begin(),
+ getPrivateCopies().end());
+ }
+
+ typedef MutableArrayRef<Expr *>::iterator inits_iterator;
+ typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
+ typedef llvm::iterator_range<inits_iterator> inits_range;
+ typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
+
+ inits_range inits() {
+ return inits_range(getInits().begin(), getInits().end());
+ }
+ inits_const_range inits() const {
+ return inits_const_range(getInits().begin(), getInits().end());
+ }
+
StmtRange children() {
return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
@@ -1278,6 +1630,71 @@ public:
}
};
+/// \brief This represents implicit clause 'flush' for the '#pragma omp flush'
+/// directive.
+/// This clause does not exist by itself, it can be only as a part of 'omp
+/// flush' 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 flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has implicit clause 'flush'
+/// with the variables 'a' and 'b'.
+///
+class OMPFlushClause : public OMPVarListClause<OMPFlushClause> {
+ /// \brief 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.
+ ///
+ OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
+ EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPFlushClause(unsigned N)
+ : OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// \brief 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 variables.
+ ///
+ static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_flush;
+ }
+};
+
} // end namespace clang
#endif
+
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index aba88d6c54..e3f0126677 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_OPERATION_KINDS_H
-#define LLVM_CLANG_AST_OPERATION_KINDS_H
+#ifndef LLVM_CLANG_AST_OPERATIONKINDS_H
+#define LLVM_CLANG_AST_OPERATIONKINDS_H
namespace clang {
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
index eece8510e9..8945c413d2 100644
--- a/include/clang/AST/ParentMap.h
+++ b/include/clang/AST/ParentMap.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_PARENTMAP_H
-#define LLVM_CLANG_PARENTMAP_H
+#ifndef LLVM_CLANG_AST_PARENTMAP_H
+#define LLVM_CLANG_AST_PARENTMAP_H
namespace clang {
class Stmt;
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 349f4c44a4..35ceabbd6b 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_PRETTY_PRINTER_H
-#define LLVM_CLANG_AST_PRETTY_PRINTER_H
+#ifndef LLVM_CLANG_AST_PRETTYPRINTER_H
+#define LLVM_CLANG_AST_PRETTYPRINTER_H
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index 8ba85c43f6..2e005ddbd0 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H
-#define LLVM_CLANG_AST_RAW_COMMENT_LIST_H
+#ifndef LLVM_CLANG_AST_RAWCOMMENTLIST_H
+#define LLVM_CLANG_AST_RAWCOMMENTLIST_H
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/SourceManager.h"
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 4befb45062..7b7799884a 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_LAYOUTINFO_H
-#define LLVM_CLANG_AST_LAYOUTINFO_H
+#ifndef LLVM_CLANG_AST_RECORDLAYOUT_H
+#define LLVM_CLANG_AST_RECORDLAYOUT_H
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclCXX.h"
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index b4c4fd6ddb..a1d36180d7 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -429,6 +429,7 @@ private:
bool TraverseFunctionHelper(FunctionDecl *D);
bool TraverseVarHelper(VarDecl *D);
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"
@@ -689,6 +690,7 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Super:
return true;
case NestedNameSpecifier::TypeSpec:
@@ -713,6 +715,7 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Super:
return true;
case NestedNameSpecifier::TypeSpec:
@@ -940,6 +943,9 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
for (const auto &E : T->exceptions()) {
TRY_TO(TraverseType(E));
}
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
})
DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
@@ -1148,6 +1154,9 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
for (const auto &E : T->exceptions()) {
TRY_TO(TraverseType(E));
}
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
})
DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
@@ -2144,21 +2153,29 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
TRY_TO(TraverseLambdaCapture(S, C));
}
- if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
- // Visit the whole type.
- TRY_TO(TraverseTypeLoc(TL));
- } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
- if (S->hasExplicitParameters()) {
- // Visit parameters.
- for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
- TRY_TO(TraverseDecl(Proto.getParam(I)));
- }
- } else {
- TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
+ TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+ FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
+
+ if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+ // Visit the whole type.
+ TRY_TO(TraverseTypeLoc(TL));
+ } else {
+ if (S->hasExplicitParameters()) {
+ // Visit parameters.
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+ TRY_TO(TraverseDecl(Proto.getParam(I)));
}
+ } else if (S->hasExplicitResultType()) {
+ TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
}
+
+ auto *T = Proto.getTypePtr();
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
}
TRY_TO(TraverseLambdaBody(S));
@@ -2259,6 +2276,7 @@ DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(TypoExpr, {})
DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
// These operators (all of them) do not need any action except
@@ -2275,6 +2293,7 @@ DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXFoldExpr, {})
DEF_TRAVERSE_STMT(AtomicExpr, {})
// These literals (all of them) do not need any action.
@@ -2301,6 +2320,12 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
return true;
}
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
+ return TraverseOMPExecutableDirective(S);
+}
+
DEF_TRAVERSE_STMT(OMPParallelDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2310,6 +2335,9 @@ DEF_TRAVERSE_STMT(OMPSimdDirective,
DEF_TRAVERSE_STMT(OMPForDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPForSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2319,12 +2347,50 @@ DEF_TRAVERSE_STMT(OMPSectionDirective,
DEF_TRAVERSE_STMT(OMPSingleDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+ TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+ TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
DEF_TRAVERSE_STMT(OMPParallelForDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTaskDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPBarrierDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPOrderedDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPAtomicDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTeamsDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
@@ -2350,6 +2416,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
+ TRY_TO(TraverseStmt(C->getCondition()));
+ return true;
+}
+
+template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
TRY_TO(TraverseStmt(C->getNumThreads()));
@@ -2397,6 +2469,42 @@ bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
+ return true;
+}
+
+template <typename Derived>
template <typename T>
bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
for (auto *E : Node->varlists()) {
@@ -2408,6 +2516,9 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
TRY_TO(VisitOMPClauseList(C));
+ for (auto *E : C->private_copies()) {
+ TRY_TO(TraverseStmt(E));
+ }
return true;
}
@@ -2415,6 +2526,12 @@ template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
OMPFirstprivateClause *C) {
TRY_TO(VisitOMPClauseList(C));
+ for (auto *E : C->private_copies()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->inits()) {
+ TRY_TO(TraverseStmt(E));
+ }
return true;
}
@@ -2467,6 +2584,12 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ 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/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 790c8e3e66..380c3b956e 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -393,6 +393,10 @@ public:
/// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
Stmt *IgnoreImplicit();
+ /// \brief Skip no-op (attributed, compound) container stmts and skip captured
+ /// stmt at the top, if \a IgnoreCaptured is true.
+ Stmt *IgnoreContainers(bool IgnoreCaptured = false);
+
const Stmt *stripLabelLikeStatements() const;
Stmt *stripLabelLikeStatements() {
return const_cast<Stmt*>(
@@ -548,14 +552,17 @@ public:
///
class CompoundStmt : public Stmt {
Stmt** Body;
- SourceLocation LBracLoc, RBracLoc;
+ SourceLocation LBraceLoc, RBraceLoc;
+
+ friend class ASTStmtReader;
+
public:
CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
SourceLocation LB, SourceLocation RB);
// \brief Build an empty compound statement with a location.
explicit CompoundStmt(SourceLocation Loc)
- : Stmt(CompoundStmtClass), Body(nullptr), LBracLoc(Loc), RBracLoc(Loc) {
+ : Stmt(CompoundStmtClass), Body(nullptr), LBraceLoc(Loc), RBraceLoc(Loc) {
CompoundStmtBits.NumStmts = 0;
}
@@ -614,13 +621,11 @@ public:
return const_reverse_body_iterator(body_begin());
}
- SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
+ SourceLocation getLocStart() const LLVM_READONLY { return LBraceLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RBraceLoc; }
- SourceLocation getLBracLoc() const { return LBracLoc; }
- void setLBracLoc(SourceLocation L) { LBracLoc = L; }
- SourceLocation getRBracLoc() const { return RBracLoc; }
- void setRBracLoc(SourceLocation L) { RBracLoc = L; }
+ SourceLocation getLBracLoc() const { return LBraceLoc; }
+ SourceLocation getRBracLoc() const { return RBraceLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CompoundStmtClass;
@@ -846,7 +851,7 @@ public:
SourceLocation getAttrLoc() const { return AttrLoc; }
ArrayRef<const Attr*> getAttrs() const {
- return ArrayRef<const Attr*>(getAttrArrayPtr(), NumAttrs);
+ return llvm::makeArrayRef(getAttrArrayPtr(), NumAttrs);
}
Stmt *getSubStmt() { return SubStmt; }
const Stmt *getSubStmt() const { return SubStmt; }
@@ -1580,18 +1585,21 @@ public:
Kind MyKind;
std::string Str;
unsigned OperandNo;
+
+ // Source range for operand references.
+ CharSourceRange Range;
public:
AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
- AsmStringPiece(unsigned OpNo, char Modifier)
- : MyKind(Operand), Str(), OperandNo(OpNo) {
- Str += Modifier;
+ AsmStringPiece(unsigned OpNo, const std::string &S, SourceLocation Begin,
+ SourceLocation End)
+ : MyKind(Operand), Str(S), OperandNo(OpNo),
+ Range(CharSourceRange::getCharRange(Begin, End)) {
}
bool isString() const { return MyKind == String; }
bool isOperand() const { return MyKind == Operand; }
const std::string &getString() const {
- assert(isString());
return Str;
}
@@ -1600,12 +1608,14 @@ public:
return OperandNo;
}
+ CharSourceRange getRange() const {
+ assert(isOperand() && "Range is currently used only for Operands.");
+ return Range;
+ }
+
/// getModifier - Get the modifier for this operand, if present. This
/// returns '\0' if there was no modifier.
- char getModifier() const {
- assert(isOperand());
- return Str[0];
- }
+ char getModifier() const;
};
/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
@@ -1780,14 +1790,14 @@ public:
//===--- Other ---===//
ArrayRef<StringRef> getAllConstraints() const {
- return ArrayRef<StringRef>(Constraints, NumInputs + NumOutputs);
+ return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
}
ArrayRef<StringRef> getClobbers() const {
- return ArrayRef<StringRef>(Clobbers, NumClobbers);
+ return llvm::makeArrayRef(Clobbers, NumClobbers);
}
ArrayRef<Expr*> getAllExprs() const {
- return ArrayRef<Expr*>(reinterpret_cast<Expr**>(Exprs),
- NumInputs + NumOutputs);
+ return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
+ NumInputs + NumOutputs);
}
StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
@@ -1972,15 +1982,18 @@ public:
/// @endcode
class CapturedStmt : public Stmt {
public:
- /// \brief The different capture forms: by 'this' or by reference, etc.
+ /// \brief The different capture forms: by 'this', by reference, capture for
+ /// variable-length array type etc.
enum VariableCaptureKind {
VCK_This,
- VCK_ByRef
+ VCK_ByRef,
+ VCK_VLAType,
};
- /// \brief Describes the capture of either a variable or 'this'.
+ /// \brief Describes the capture of either a variable, or 'this', or
+ /// variable-length array type.
class Capture {
- llvm::PointerIntPair<VarDecl *, 1, VariableCaptureKind> VarAndKind;
+ llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
SourceLocation Loc;
public:
@@ -2002,6 +2015,10 @@ public:
case VCK_ByRef:
assert(Var && "capturing by reference must have a variable!");
break;
+ case VCK_VLAType:
+ assert(!Var &&
+ "Variable-length array type capture cannot have a variable!");
+ break;
}
}
@@ -2016,13 +2033,20 @@ public:
bool capturesThis() const { return getCaptureKind() == VCK_This; }
/// \brief Determine whether this capture handles a variable.
- bool capturesVariable() const { return getCaptureKind() != VCK_This; }
+ bool capturesVariable() const { return getCaptureKind() == VCK_ByRef; }
+
+ /// \brief Determine whether this capture handles a variable-length array
+ /// type.
+ bool capturesVariableArrayType() const {
+ return getCaptureKind() == VCK_VLAType;
+ }
/// \brief Retrieve the declaration of the variable being captured.
///
- /// This operation is only valid if this capture does not capture 'this'.
+ /// This operation is only valid if this capture captures a variable.
VarDecl *getCapturedVar() const {
- assert(!capturesThis() && "No variable available for 'this' capture");
+ assert(capturesVariable() &&
+ "No variable available for 'this' or VAT capture");
return VarAndKind.getPointer();
}
friend class ASTStmtReader;
diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h
index a3e9e1e093..ab636a5ddc 100644
--- a/include/clang/AST/StmtGraphTraits.h
+++ b/include/clang/AST/StmtGraphTraits.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
-#define LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
+#ifndef LLVM_CLANG_AST_STMTGRAPHTRAITS_H
+#define LLVM_CLANG_AST_STMTGRAPHTRAITS_H
#include "clang/AST/Stmt.h"
#include "llvm/ADT/DepthFirstIterator.h"
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index 18c55166be..6ffe74f2d7 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_STMT_ITR_H
-#define LLVM_CLANG_AST_STMT_ITR_H
+#ifndef LLVM_CLANG_AST_STMTITERATOR_H
+#define LLVM_CLANG_AST_STMTITERATOR_H
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index f6fe473f7b..6a2832cdad 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -83,7 +83,10 @@ protected:
///
/// /param S Associated statement.
///
- void setAssociatedStmt(Stmt *S) { *child_begin() = S; }
+ void setAssociatedStmt(Stmt *S) {
+ assert(hasAssociatedStmt() && "no associated statement.");
+ *child_begin() = S;
+ }
public:
/// \brief Iterates over a filtered subrange of clauses applied to a
@@ -125,6 +128,13 @@ public:
operator bool() { return Current != End; }
};
+ /// \brief Gets a single clause of the specified kind \a K associated with the
+ /// current directive iff there is only one clause of this kind (and assertion
+ /// is fired if there is more than one clause is associated with the
+ /// directive). Returns nullptr if no clause of kind \a K is associated with
+ /// the directive.
+ const OMPClause *getSingleClause(OpenMPClauseKind K) const;
+
/// \brief Returns starting location of directive kind.
SourceLocation getLocStart() const { return StartLoc; }
/// \brief Returns ending location of directive.
@@ -150,8 +160,14 @@ public:
///
OMPClause *getClause(unsigned i) const { return clauses()[i]; }
+ /// \brief Returns true if directive has associated statement.
+ bool hasAssociatedStmt() const { return NumChildren > 0; }
+
/// \brief Returns statement associated with the directive.
- Stmt *getAssociatedStmt() const { return const_cast<Stmt *>(*child_begin()); }
+ Stmt *getAssociatedStmt() const {
+ assert(hasAssociatedStmt() && "no associated statement.");
+ return const_cast<Stmt *>(*child_begin());
+ }
OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
@@ -161,6 +177,8 @@ public:
}
child_range children() {
+ if (!hasAssociatedStmt())
+ return child_range();
Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
return child_range(ChildStorage, ChildStorage + NumChildren);
}
@@ -227,6 +245,168 @@ public:
}
};
+/// \brief This is a common base class for loop directives ('omp simd', 'omp
+/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
+///
+class OMPLoopDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Number of collapsed loops as specified by 'collapse' clause.
+ unsigned CollapsedNum;
+
+ /// \brief Offsets to the stored exprs.
+ enum {
+ AssociatedStmtOffset = 0,
+ IterationVariableOffset = 1,
+ LastIterationOffset = 2,
+ CalcLastIterationOffset = 3,
+ PreConditionOffset = 4,
+ CondOffset = 5,
+ SeparatedCondOffset = 6,
+ InitOffset = 7,
+ IncOffset = 8,
+ ArraysOffset = 9
+ };
+
+ /// \brief Get the counters storage.
+ MutableArrayRef<Expr *> getCounters() {
+ Expr **Storage =
+ reinterpret_cast<Expr **>(&(*(std::next(child_begin(), ArraysOffset))));
+ return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+ }
+
+ /// \brief Get the updates storage.
+ MutableArrayRef<Expr *> getUpdates() {
+ Expr **Storage = reinterpret_cast<Expr **>(
+ &*std::next(child_begin(), ArraysOffset + CollapsedNum));
+ return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+ }
+
+ /// \brief Get the final counter updates storage.
+ MutableArrayRef<Expr *> getFinals() {
+ Expr **Storage = reinterpret_cast<Expr **>(
+ &*std::next(child_begin(), ArraysOffset + 2 * CollapsedNum));
+ return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+ }
+
+protected:
+ /// \brief Build instance of loop directive of class \a Kind.
+ ///
+ /// \param SC Statement class.
+ /// \param Kind Kind of OpenMP directive.
+ /// \param StartLoc Starting location of the directive (directive keyword).
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
+ /// \param NumClauses Number of clauses.
+ /// \param NumSpecialChildren Number of additional directive-specific stmts.
+ ///
+ template <typename T>
+ OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses,
+ unsigned NumSpecialChildren = 0)
+ : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
+ numLoopChildren(CollapsedNum) +
+ NumSpecialChildren),
+ CollapsedNum(CollapsedNum) {}
+
+ /// \brief Children number.
+ static unsigned numLoopChildren(unsigned CollapsedNum) {
+ return ArraysOffset + 3 * CollapsedNum; // Counters, Updates and Finals
+ }
+
+ void setIterationVariable(Expr *IV) {
+ *std::next(child_begin(), IterationVariableOffset) = IV;
+ }
+ void setLastIteration(Expr *LI) {
+ *std::next(child_begin(), LastIterationOffset) = LI;
+ }
+ void setCalcLastIteration(Expr *CLI) {
+ *std::next(child_begin(), CalcLastIterationOffset) = CLI;
+ }
+ void setPreCond(Expr *PC) {
+ *std::next(child_begin(), PreConditionOffset) = PC;
+ }
+ void setCond(Expr *Cond, Expr *SeparatedCond) {
+ *std::next(child_begin(), CondOffset) = Cond;
+ *std::next(child_begin(), SeparatedCondOffset) = SeparatedCond;
+ }
+ void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
+ void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
+ void setCounters(ArrayRef<Expr *> A);
+ void setUpdates(ArrayRef<Expr *> A);
+ void setFinals(ArrayRef<Expr *> A);
+
+public:
+ /// \brief Get number of collapsed loops.
+ unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+ Expr *getIterationVariable() const {
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(), IterationVariableOffset)));
+ }
+ Expr *getLastIteration() const {
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(), LastIterationOffset)));
+ }
+ Expr *getCalcLastIteration() const {
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(), CalcLastIterationOffset)));
+ }
+ Expr *getPreCond() const {
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(), PreConditionOffset)));
+ }
+ Expr *getCond(bool SeparateIter) const {
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(),
+ (SeparateIter ? SeparatedCondOffset : CondOffset))));
+ }
+ Expr *getInit() const {
+ return const_cast<Expr *>(
+ reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
+ }
+ Expr *getInc() const {
+ return const_cast<Expr *>(
+ reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
+ }
+ const Stmt *getBody() const {
+ // This relies on the loop form is already checked by Sema.
+ Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
+ Body = cast<ForStmt>(Body)->getBody();
+ for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
+ Body = Body->IgnoreContainers();
+ Body = cast<ForStmt>(Body)->getBody();
+ }
+ return Body;
+ }
+
+ ArrayRef<Expr *> counters() { return getCounters(); }
+
+ ArrayRef<Expr *> counters() const {
+ return const_cast<OMPLoopDirective *>(this)->getCounters();
+ }
+
+ ArrayRef<Expr *> updates() { return getUpdates(); }
+
+ ArrayRef<Expr *> updates() const {
+ return const_cast<OMPLoopDirective *>(this)->getUpdates();
+ }
+
+ ArrayRef<Expr *> finals() { return getFinals(); }
+
+ ArrayRef<Expr *> finals() const {
+ return const_cast<OMPLoopDirective *>(this)->getFinals();
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPSimdDirectiveClass ||
+ T->getStmtClass() == OMPForDirectiveClass ||
+ T->getStmtClass() == OMPForSimdDirectiveClass ||
+ T->getStmtClass() == OMPParallelForDirectiveClass ||
+ T->getStmtClass() == OMPParallelForSimdDirectiveClass;
+ }
+};
+
/// \brief This represents '#pragma omp simd' directive.
///
/// \code
@@ -236,10 +416,8 @@ public:
/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
///
-class OMPSimdDirective : public OMPExecutableDirective {
+class OMPSimdDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Number of collapsed loops as specified by 'collapse' clause.
- unsigned CollapsedNum;
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
@@ -249,9 +427,8 @@ class OMPSimdDirective : public OMPExecutableDirective {
///
OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
- EndLoc, NumClauses, 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
+ EndLoc, CollapsedNum, NumClauses) {}
/// \brief Build an empty directive.
///
@@ -259,10 +436,9 @@ class OMPSimdDirective : public OMPExecutableDirective {
/// \param NumClauses Number of clauses.
///
explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
+ SourceLocation(), SourceLocation(), CollapsedNum,
+ NumClauses) {}
public:
/// \brief Creates directive with a list of \a Clauses.
@@ -273,11 +449,24 @@ public:
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt);
+ /// \param IV Loop iteration variable for CodeGen.
+ /// \param LastIteration Loop last iteration number for CodeGen.
+ /// \param CalcLastIteration Calculation of last iteration.
+ /// \param PreCond Pre-condition.
+ /// \param Cond Condition.
+ /// \param SeparatedCond Condition with 1 iteration separated.
+ /// \param Inc Loop increment.
+ /// \param Counters Loop counters.
+ /// \param Updates Expressions for loop counters update for CodeGen.
+ /// \param Finals Final loop counter values for GodeGen.
+ ///
+ static OMPSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
+ Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
+ Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
+ ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
/// \brief Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -289,8 +478,6 @@ public:
static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
unsigned CollapsedNum, EmptyShell);
- unsigned getCollapsedNumber() const { return CollapsedNum; }
-
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPSimdDirectiveClass;
}
@@ -305,10 +492,8 @@ public:
/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
/// and 'd'.
///
-class OMPForDirective : public OMPExecutableDirective {
+class OMPForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Number of collapsed loops as specified by 'collapse' clause.
- unsigned CollapsedNum;
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
@@ -318,9 +503,8 @@ class OMPForDirective : public OMPExecutableDirective {
///
OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc,
- EndLoc, NumClauses, 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
+ CollapsedNum, NumClauses) {}
/// \brief Build an empty directive.
///
@@ -328,10 +512,8 @@ class OMPForDirective : public OMPExecutableDirective {
/// \param NumClauses Number of clauses.
///
explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
public:
/// \brief Creates directive with a list of \a Clauses.
@@ -342,11 +524,24 @@ public:
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt);
+ /// \param IV Loop iteration variable for CodeGen.
+ /// \param LastIteration Loop last iteration number for CodeGen.
+ /// \param CalcLastIteration Calculation of last iteration.
+ /// \param PreCond Pre-condition.
+ /// \param Cond Condition.
+ /// \param SeparatedCond Condition with 1 iteration separated.
+ /// \param Inc Loop increment.
+ /// \param Counters Loop counters.
+ /// \param Updates Expressions for loop counters update for CodeGen.
+ /// \param Finals Final loop counter values for GodeGen.
+ ///
+ static OMPForDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
+ Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
+ Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
+ ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
/// \brief Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -358,13 +553,88 @@ public:
static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
unsigned CollapsedNum, EmptyShell);
- unsigned getCollapsedNumber() const { return CollapsedNum; }
-
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPForDirectiveClass;
}
};
+/// \brief This represents '#pragma omp for simd' directive.
+///
+/// \code
+/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp for simd' has clauses 'private'
+/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
+/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
+///
+class OMPForSimdDirective : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ /// \brief 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 CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
+ StartLoc, EndLoc, CollapsedNum, NumClauses) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
+ SourceLocation(), SourceLocation(), CollapsedNum,
+ NumClauses) {}
+
+public:
+ /// \brief 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 CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param IV Loop iteration variable for CodeGen.
+ /// \param LastIteration Loop last iteration number for CodeGen.
+ /// \param CalcLastIteration Calculation of last iteration.
+ /// \param PreCond Pre-condition.
+ /// \param Cond Condition.
+ /// \param SeparatedCond Condition with 1 iteration separated.
+ /// \param Inc Loop increment.
+ /// \param Counters Loop counters.
+ /// \param Updates Expressions for loop counters update for CodeGen.
+ /// \param Finals Final loop counter values for GodeGen.
+ ///
+ static OMPForSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
+ Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
+ Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
+ ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
+
+ /// \brief Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPForSimdDirectiveClass;
+ }
+};
+
/// \brief This represents '#pragma omp sections' directive.
///
/// \code
@@ -527,6 +797,116 @@ public:
}
};
+/// \brief This represents '#pragma omp master' directive.
+///
+/// \code
+/// #pragma omp master
+/// \endcode
+///
+class OMPMasterDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
+ StartLoc, EndLoc, 0, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPMasterDirective()
+ : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
+ SourceLocation(), SourceLocation(), 0, 1) {}
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPMasterDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPMasterDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp critical' directive.
+///
+/// \code
+/// #pragma omp critical
+/// \endcode
+///
+class OMPCriticalDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Name of the directive.
+ DeclarationNameInfo DirName;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param Name Name of the directive.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
+ SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
+ StartLoc, EndLoc, 0, 1),
+ DirName(Name) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPCriticalDirective()
+ : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
+ SourceLocation(), SourceLocation(), 0, 1),
+ DirName() {}
+
+ /// \brief Set name of the directive.
+ ///
+ /// \param Name Name of the directive.
+ ///
+ void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param Name Name of the directive.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPCriticalDirective *
+ Create(const ASTContext &C, const DeclarationNameInfo &Name,
+ SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ /// \brief Return name of the directive.
+ ///
+ DeclarationNameInfo getDirectiveName() const { return DirName; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPCriticalDirectiveClass;
+ }
+};
+
/// \brief This represents '#pragma omp parallel for' directive.
///
/// \code
@@ -536,10 +916,8 @@ public:
/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
/// variables 'c' and 'd'.
///
-class OMPParallelForDirective : public OMPExecutableDirective {
+class OMPParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Number of collapsed loops as specified by 'collapse' clause.
- unsigned CollapsedNum;
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
@@ -549,10 +927,8 @@ class OMPParallelForDirective : public OMPExecutableDirective {
///
OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
- OMPD_parallel_for, StartLoc, EndLoc, NumClauses,
- 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
+ StartLoc, EndLoc, CollapsedNum, NumClauses) {}
/// \brief Build an empty directive.
///
@@ -560,10 +936,9 @@ class OMPParallelForDirective : public OMPExecutableDirective {
/// \param NumClauses Number of clauses.
///
explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
- OMPD_parallel_for, SourceLocation(),
- SourceLocation(), NumClauses, 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
+ SourceLocation(), SourceLocation(), CollapsedNum,
+ NumClauses) {}
public:
/// \brief Creates directive with a list of \a Clauses.
@@ -574,11 +949,24 @@ public:
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param IV Loop iteration variable for CodeGen.
+ /// \param LastIteration Loop last iteration number for CodeGen.
+ /// \param CalcLastIteration Calculation of last iteration.
+ /// \param PreCond Pre-condition.
+ /// \param Cond Condition.
+ /// \param SeparatedCond Condition with 1 iteration separated.
+ /// \param Inc Loop increment.
+ /// \param Counters Loop counters.
+ /// \param Updates Expressions for loop counters update for CodeGen.
+ /// \param Finals Final loop counter values for GodeGen.
///
static OMPParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt);
+ Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
+ Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
+ Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
+ ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
/// \brief Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -592,13 +980,92 @@ public:
unsigned CollapsedNum,
EmptyShell);
- unsigned getCollapsedNumber() const { return CollapsedNum; }
-
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelForDirectiveClass;
}
};
+/// \brief This represents '#pragma omp parallel for simd' directive.
+///
+/// \code
+/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp parallel for simd' has clauses
+/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
+/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
+/// 'd'.
+///
+class OMPParallelForSimdDirective : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ /// \brief 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 CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
+ OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
+ NumClauses) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
+ OMPD_parallel_for_simd, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+ /// \brief 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 CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param IV Loop iteration variable for CodeGen.
+ /// \param LastIteration Loop last iteration number for CodeGen.
+ /// \param CalcLastIteration Calculation of last iteration.
+ /// \param PreCond Pre-condition.
+ /// \param Cond Condition.
+ /// \param SeparatedCond Condition with 1 iteration separated.
+ /// \param Inc Loop increment.
+ /// \param Counters Loop counters.
+ /// \param Updates Expressions for loop counters update for CodeGen.
+ /// \param Finals Final loop counter values for GodeGen.
+ ///
+ static OMPParallelForSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
+ Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
+ Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
+ ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
+
+ /// \brief Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
+ }
+};
+
/// \brief This represents '#pragma omp parallel sections' directive.
///
/// \code
@@ -658,6 +1125,502 @@ public:
}
};
+/// \brief This represents '#pragma omp task' directive.
+///
+/// \code
+/// #pragma omp task private(a,b) final(d)
+/// \endcode
+/// In this example directive '#pragma omp task' has clauses 'private' with the
+/// variables 'a' and 'b' and 'final' with condition 'd'.
+///
+class OMPTaskDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief 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.
+ ///
+ OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
+ EndLoc, NumClauses, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTaskDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1) {}
+
+public:
+ /// \brief 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.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTaskDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp taskyield' directive.
+///
+/// \code
+/// #pragma omp taskyield
+/// \endcode
+///
+class OMPTaskyieldDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
+ StartLoc, EndLoc, 0, 0) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPTaskyieldDirective()
+ : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
+ SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ ///
+ static OMPTaskyieldDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTaskyieldDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp barrier' directive.
+///
+/// \code
+/// #pragma omp barrier
+/// \endcode
+///
+class OMPBarrierDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
+ StartLoc, EndLoc, 0, 0) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPBarrierDirective()
+ : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
+ SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ ///
+ static OMPBarrierDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPBarrierDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp taskwait' directive.
+///
+/// \code
+/// #pragma omp taskwait
+/// \endcode
+///
+class OMPTaskwaitDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
+ StartLoc, EndLoc, 0, 0) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPTaskwaitDirective()
+ : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
+ SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ ///
+ static OMPTaskwaitDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTaskwaitDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp flush' directive.
+///
+/// \code
+/// #pragma omp flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
+/// and 'b'.
+/// 'omp flush' directive does not have clauses but have an optional list of
+/// variables to flush. This list of variables is stored within some fake clause
+/// FlushClause.
+class OMPFlushDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief 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.
+ ///
+ OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
+ StartLoc, EndLoc, NumClauses, 0) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPFlushDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 0) {}
+
+public:
+ /// \brief 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 OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPFlushDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPFlushDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp ordered' directive.
+///
+/// \code
+/// #pragma omp ordered
+/// \endcode
+///
+class OMPOrderedDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
+ StartLoc, EndLoc, 0, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPOrderedDirective()
+ : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
+ SourceLocation(), SourceLocation(), 0, 1) {}
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPOrderedDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPOrderedDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPOrderedDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp atomic' directive.
+///
+/// \code
+/// #pragma omp atomic capture
+/// \endcode
+/// In this example directive '#pragma omp atomic' has clause 'capture'.
+///
+class OMPAtomicDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief 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.
+ ///
+ OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
+ StartLoc, EndLoc, NumClauses, 4) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPAtomicDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 4) {}
+
+ /// \brief Set 'x' part of the associated expression/statement.
+ void setX(Expr *X) { *std::next(child_begin()) = X; }
+ /// \brief Set 'v' part of the associated expression/statement.
+ void setV(Expr *V) { *std::next(child_begin(), 2) = V; }
+ /// \brief Set 'expr' part of the associated expression/statement.
+ void setExpr(Expr *E) { *std::next(child_begin(), 3) = E; }
+
+public:
+ /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
+ /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
+ /// detailed description of 'x', 'v' and 'expr').
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param X 'x' part of the associated expression/statement.
+ /// \param V 'v' part of the associated expression/statement.
+ /// \param E 'expr' part of the associated expression/statement.
+ ///
+ static OMPAtomicDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
+ Expr *E);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ /// \brief Get 'x' part of the associated expression/statement.
+ Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
+ const Expr *getX() const {
+ return cast_or_null<Expr>(*std::next(child_begin()));
+ }
+ /// \brief Get 'v' part of the associated expression/statement.
+ Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 2)); }
+ const Expr *getV() const {
+ return cast_or_null<Expr>(*std::next(child_begin(), 2));
+ }
+ /// \brief Get 'expr' part of the associated expression/statement.
+ Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
+ const Expr *getExpr() const {
+ return cast_or_null<Expr>(*std::next(child_begin(), 3));
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPAtomicDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp target' directive.
+///
+/// \code
+/// #pragma omp target if(a)
+/// \endcode
+/// In this example directive '#pragma omp target' has clause 'if' with
+/// condition 'a'.
+///
+class OMPTargetDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief 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.
+ ///
+ OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
+ StartLoc, EndLoc, NumClauses, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTargetDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1) {}
+
+public:
+ /// \brief 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.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPTargetDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTargetDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp teams' directive.
+///
+/// \code
+/// #pragma omp teams if(a)
+/// \endcode
+/// In this example directive '#pragma omp teams' has clause 'if' with
+/// condition 'a'.
+///
+class OMPTeamsDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief 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.
+ ///
+ OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
+ StartLoc, EndLoc, NumClauses, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTeamsDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1) {}
+
+public:
+ /// \brief 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.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTeamsDirectiveClass;
+ }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 9e4a577c4c..f3c6440f40 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -18,6 +18,7 @@
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -75,7 +76,7 @@ private:
struct DA {
unsigned Kind;
- bool ForRefParam;
+ void *QT;
ValueDecl *D;
};
struct I {
@@ -131,11 +132,11 @@ public:
/// \brief Construct a template argument that refers to a
/// declaration, which is either an external declaration or a
/// template declaration.
- TemplateArgument(ValueDecl *D, bool ForRefParam) {
+ TemplateArgument(ValueDecl *D, QualType QT) {
assert(D && "Expected decl");
DeclArg.Kind = Declaration;
+ DeclArg.QT = QT.getAsOpaquePtr();
DeclArg.D = D;
- DeclArg.ForRefParam = ForRefParam;
}
/// \brief Construct an integral constant template argument. The memory to
@@ -248,11 +249,9 @@ public:
return DeclArg.D;
}
- /// \brief Retrieve whether a declaration is binding to a
- /// reference parameter in a declaration non-type template argument.
- bool isDeclForReferenceParam() const {
+ QualType getParamTypeForDecl() const {
assert(getKind() == Declaration && "Unexpected kind");
- return DeclArg.ForRefParam;
+ return QualType::getFromOpaquePtr(DeclArg.QT);
}
/// \brief Retrieve the type for null non-type template argument.
@@ -327,6 +326,12 @@ public:
return Args.Args + Args.NumArgs;
}
+ /// \brief Iterator range referencing all of the elements of a template
+ /// argument pack.
+ llvm::iterator_range<pack_iterator> pack_elements() const {
+ return llvm::make_range(pack_begin(), pack_end());
+ }
+
/// \brief The number of template arguments in the given template argument
/// pack.
unsigned pack_size() const {
@@ -337,7 +342,7 @@ public:
/// \brief Return the array of arguments in this template argument pack.
ArrayRef<TemplateArgument> getPackAsArray() const {
assert(getKind() == Pack);
- return ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
+ return llvm::makeArrayRef(Args.Args, Args.NumArgs);
}
/// \brief Determines whether two template arguments are superficially the
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index a20e43413c..4f194b022d 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1245,6 +1245,7 @@ protected:
class FunctionTypeBitfields {
friend class FunctionType;
+ friend class FunctionProtoType;
unsigned : NumTypeBits;
@@ -1259,6 +1260,11 @@ protected:
/// C++ 8.3.5p4: The return type, the parameter type list and the
/// cv-qualifier-seq, [...], are part of the function type.
unsigned TypeQuals : 3;
+
+ /// \brief The ref-qualifier associated with a \c FunctionProtoType.
+ ///
+ /// This is a value of type \c RefQualifierKind.
+ unsigned RefQualifier : 2;
};
class ObjCObjectTypeBitfields {
@@ -2765,7 +2771,7 @@ class FunctionType : public Type {
protected:
FunctionType(TypeClass tc, QualType res,
- unsigned typeQuals, QualType Canonical, bool Dependent,
+ QualType Canonical, bool Dependent,
bool InstantiationDependent,
bool VariablyModified, bool ContainsUnexpandedParameterPack,
ExtInfo Info)
@@ -2773,7 +2779,6 @@ protected:
ContainsUnexpandedParameterPack),
ResultType(res) {
FunctionTypeBits.ExtInfo = Info.Bits;
- FunctionTypeBits.TypeQuals = typeQuals;
}
unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
@@ -2810,7 +2815,7 @@ public:
/// no information available about its arguments.
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
- : FunctionType(FunctionNoProto, Result, 0, Canonical,
+ : FunctionType(FunctionNoProto, Result, Canonical,
/*Dependent=*/false, /*InstantiationDependent=*/false,
Result->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false, Info) {}
@@ -2844,33 +2849,51 @@ public:
/// type.
class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
public:
+ struct ExceptionSpecInfo {
+ ExceptionSpecInfo()
+ : Type(EST_None), NoexceptExpr(nullptr),
+ SourceDecl(nullptr), SourceTemplate(nullptr) {}
+
+ ExceptionSpecInfo(ExceptionSpecificationType EST)
+ : Type(EST), NoexceptExpr(nullptr), SourceDecl(nullptr),
+ SourceTemplate(nullptr) {}
+
+ /// The kind of exception specification this is.
+ ExceptionSpecificationType Type;
+ /// Explicitly-specified list of exception types.
+ ArrayRef<QualType> Exceptions;
+ /// Noexcept expression, if this is EST_ComputedNoexcept.
+ Expr *NoexceptExpr;
+ /// The function whose exception specification this is, for
+ /// EST_Unevaluated and EST_Uninstantiated.
+ FunctionDecl *SourceDecl;
+ /// The function template whose exception specification this is instantiated
+ /// from, for EST_Uninstantiated.
+ FunctionDecl *SourceTemplate;
+ };
+
/// ExtProtoInfo - Extra information about a function prototype.
struct ExtProtoInfo {
ExtProtoInfo()
: Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
- Exceptions(nullptr), NoexceptExpr(nullptr),
- ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr),
- ConsumedParameters(nullptr) {}
+ RefQualifier(RQ_None), ConsumedParameters(nullptr) {}
ExtProtoInfo(CallingConv CC)
: ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
- Exceptions(nullptr), NoexceptExpr(nullptr),
- ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr),
- ConsumedParameters(nullptr) {}
+ RefQualifier(RQ_None), ConsumedParameters(nullptr) {}
+
+ ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O) {
+ ExtProtoInfo Result(*this);
+ Result.ExceptionSpec = O;
+ return Result;
+ }
FunctionType::ExtInfo ExtInfo;
bool Variadic : 1;
bool HasTrailingReturn : 1;
unsigned char TypeQuals;
- ExceptionSpecificationType ExceptionSpecType;
RefQualifierKind RefQualifier;
- unsigned NumExceptions;
- const QualType *Exceptions;
- Expr *NoexceptExpr;
- FunctionDecl *ExceptionSpecDecl;
- FunctionDecl *ExceptionSpecTemplate;
+ ExceptionSpecInfo ExceptionSpec;
const bool *ConsumedParameters;
};
@@ -2896,7 +2919,7 @@ private:
unsigned NumExceptions : 9;
/// ExceptionSpecType - The type of exception specification this function has.
- unsigned ExceptionSpecType : 3;
+ unsigned ExceptionSpecType : 4;
/// HasAnyConsumedParams - Whether this function has any consumed parameters.
unsigned HasAnyConsumedParams : 1;
@@ -2907,11 +2930,6 @@ private:
/// HasTrailingReturn - Whether this function has a trailing return type.
unsigned HasTrailingReturn : 1;
- /// \brief The ref-qualifier associated with a \c FunctionProtoType.
- ///
- /// This is a value of type \c RefQualifierKind.
- unsigned RefQualifier : 2;
-
// ParamInfo - There is an variable size array after the class in memory that
// holds the parameter types.
@@ -2952,7 +2970,7 @@ public:
return param_type_begin()[i];
}
ArrayRef<QualType> getParamTypes() const {
- return ArrayRef<QualType>(param_type_begin(), param_type_end());
+ return llvm::makeArrayRef(param_type_begin(), param_type_end());
}
ExtProtoInfo getExtProtoInfo() const {
@@ -2960,19 +2978,18 @@ public:
EPI.ExtInfo = getExtInfo();
EPI.Variadic = isVariadic();
EPI.HasTrailingReturn = hasTrailingReturn();
- EPI.ExceptionSpecType = getExceptionSpecType();
+ EPI.ExceptionSpec.Type = getExceptionSpecType();
EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
EPI.RefQualifier = getRefQualifier();
- if (EPI.ExceptionSpecType == EST_Dynamic) {
- EPI.NumExceptions = NumExceptions;
- EPI.Exceptions = exception_begin();
- } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
- EPI.NoexceptExpr = getNoexceptExpr();
- } else if (EPI.ExceptionSpecType == EST_Uninstantiated) {
- EPI.ExceptionSpecDecl = getExceptionSpecDecl();
- EPI.ExceptionSpecTemplate = getExceptionSpecTemplate();
- } else if (EPI.ExceptionSpecType == EST_Unevaluated) {
- EPI.ExceptionSpecDecl = getExceptionSpecDecl();
+ if (EPI.ExceptionSpec.Type == EST_Dynamic) {
+ EPI.ExceptionSpec.Exceptions = exceptions();
+ } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) {
+ EPI.ExceptionSpec.NoexceptExpr = getNoexceptExpr();
+ } else if (EPI.ExceptionSpec.Type == EST_Uninstantiated) {
+ EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
+ EPI.ExceptionSpec.SourceTemplate = getExceptionSpecTemplate();
+ } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) {
+ EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
}
if (hasAnyConsumedParams())
EPI.ConsumedParameters = getConsumedParamsBuffer();
@@ -2995,6 +3012,8 @@ public:
bool hasNoexceptExceptionSpec() const {
return isNoexceptExceptionSpec(getExceptionSpecType());
}
+ /// \brief Return whether this function has a dependent exception spec.
+ bool hasDependentExceptionSpec() const;
/// \brief Result type of getNoexceptSpec().
enum NoexceptResult {
NR_NoNoexcept, ///< There is no noexcept specifier.
@@ -3057,7 +3076,7 @@ public:
/// \brief Retrieve the ref-qualifier associated with this function type.
RefQualifierKind getRefQualifier() const {
- return static_cast<RefQualifierKind>(RefQualifier);
+ return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier);
}
typedef const QualType *param_type_iterator;
@@ -3074,10 +3093,9 @@ public:
}
typedef const QualType *exception_iterator;
- typedef llvm::iterator_range<exception_iterator> exception_range;
- exception_range exceptions() const {
- return exception_range(exception_begin(), exception_end());
+ ArrayRef<QualType> exceptions() const {
+ return llvm::makeArrayRef(exception_begin(), exception_end());
}
exception_iterator exception_begin() const {
// exceptions begin where arguments end
@@ -3416,6 +3434,7 @@ public:
attr_stdcall,
attr_thiscall,
attr_pascal,
+ attr_vectorcall,
attr_pnaclcall,
attr_inteloclbicc,
attr_ms_abi,
@@ -5231,8 +5250,8 @@ template <typename T> const T *Type::castAs() const {
ArrayType_cannot_be_used_with_getAs<T> at;
(void) at;
- assert(isa<T>(CanonicalType));
if (const T *ty = dyn_cast<T>(this)) return ty;
+ assert(isa<T>(CanonicalType));
return cast<T>(getUnqualifiedDesugaredType());
}
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 3648d2a5c2..4f3c811ce2 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -1208,7 +1208,7 @@ public:
}
ArrayRef<ParmVarDecl *> getParams() const {
- return ArrayRef<ParmVarDecl *>(getParmArray(), getNumParams());
+ return llvm::makeArrayRef(getParmArray(), getNumParams());
}
// ParmVarDecls* are stored after Info, one for each parameter.
@@ -1567,6 +1567,8 @@ public:
void setUnderlyingTInfo(TypeSourceInfo* TI) const {
this->getLocalData()->UnderlyingTInfo = TI;
}
+
+ void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
// FIXME: location of the 'decltype' and parens.
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
index 9c9f15e953..392e544d90 100644
--- a/include/clang/AST/TypeOrdering.h
+++ b/include/clang/AST/TypeOrdering.h
@@ -16,8 +16,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TYPE_ORDERING_H
-#define LLVM_CLANG_TYPE_ORDERING_H
+#ifndef LLVM_CLANG_AST_TYPEORDERING_H
+#define LLVM_CLANG_AST_TYPEORDERING_H
#include "clang/AST/CanonicalType.h"
#include "clang/AST/Type.h"
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 2ef5800c30..a11f22d201 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -98,7 +98,7 @@ class UnresolvedSetImpl {
private:
template <unsigned N> friend class UnresolvedSet;
UnresolvedSetImpl() {}
- UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION;
+ UnresolvedSetImpl(const UnresolvedSetImpl &) {}
public:
// We don't currently support assignment through this iterator, so we might