aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-06-21 14:00:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-06-21 14:00:56 +0000
commit2e645aa5697838f16ec570eb07c2bee7e13d0e0b (patch)
treea764184c2fc9486979b074250b013a0937ee64e5 /include/clang/AST
parent798321d8eb5630cd4a8f490a4f25e32ef195fb07 (diff)
downloadsrc-2e645aa5697838f16ec570eb07c2bee7e13d0e0b.tar.gz
src-2e645aa5697838f16ec570eb07c2bee7e13d0e0b.zip
Vendor import of clang trunk r240225:vendor/clang/clang-trunk-r240225
Notes
Notes: svn path=/vendor/clang/dist/; revision=284679 svn path=/vendor/clang/clang-trunk-r240225/; revision=284680; tag=vendor/clang/clang-trunk-r240225
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTContext.h30
-rw-r--r--include/clang/AST/CommentParser.h6
-rw-r--r--include/clang/AST/DataRecursiveASTVisitor.h10
-rw-r--r--include/clang/AST/DeclBase.h7
-rw-r--r--include/clang/AST/DeclCXX.h2
-rw-r--r--include/clang/AST/DeclObjC.h34
-rw-r--r--include/clang/AST/DeclTemplate.h193
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h71
-rw-r--r--include/clang/AST/Expr.h78
-rw-r--r--include/clang/AST/OpenMPClause.h4
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h5
-rw-r--r--include/clang/AST/StmtOpenMP.h86
-rw-r--r--include/clang/AST/Type.h47
13 files changed, 445 insertions, 128 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 049221ad9144..da288c4fe5ed 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -1854,6 +1854,36 @@ public:
getCanonicalType(T2).getTypePtr();
}
+ bool hasSameNullabilityTypeQualifier(QualType SubT, QualType SuperT,
+ bool IsParam) const {
+ auto SubTnullability = SubT->getNullability(*this);
+ auto SuperTnullability = SuperT->getNullability(*this);
+ if (SubTnullability.hasValue() == SuperTnullability.hasValue()) {
+ // Neither has nullability; return true
+ if (!SubTnullability)
+ return true;
+ // Both have nullability qualifier.
+ if (*SubTnullability == *SuperTnullability ||
+ *SubTnullability == NullabilityKind::Unspecified ||
+ *SuperTnullability == NullabilityKind::Unspecified)
+ return true;
+
+ if (IsParam) {
+ // Ok for the superclass method parameter to be "nonnull" and the subclass
+ // method parameter to be "nullable"
+ return (*SuperTnullability == NullabilityKind::NonNull &&
+ *SubTnullability == NullabilityKind::Nullable);
+ }
+ else {
+ // For the return type, it's okay for the superclass method to specify
+ // "nullable" and the subclass method specify "nonnull"
+ return (*SuperTnullability == NullabilityKind::Nullable &&
+ *SubTnullability == NullabilityKind::NonNull);
+ }
+ }
+ return true;
+ }
+
bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
const ObjCMethodDecl *MethodImp);
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
index 42bf4c989a23..fa8862899c14 100644
--- a/include/clang/AST/CommentParser.h
+++ b/include/clang/AST/CommentParser.h
@@ -75,11 +75,7 @@ class Parser {
return;
MoreLATokens.push_back(Tok);
- for (const Token *I = &Toks.back(),
- *B = &Toks.front();
- I != B; --I) {
- MoreLATokens.push_back(*I);
- }
+ MoreLATokens.append(Toks.rbegin(), std::prev(Toks.rend()));
Tok = Toks[0];
}
diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h
index 971841e8fb5d..ef8817659338 100644
--- a/include/clang/AST/DataRecursiveASTVisitor.h
+++ b/include/clang/AST/DataRecursiveASTVisitor.h
@@ -531,10 +531,7 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
}
}
- for (SmallVectorImpl<Stmt *>::reverse_iterator RI = StmtsToEnqueue.rbegin(),
- RE = StmtsToEnqueue.rend();
- RI != RE; ++RI)
- Queue.push_back(*RI);
+ Queue.append(StmtsToEnqueue.rbegin(), StmtsToEnqueue.rend());
}
return true;
@@ -2204,9 +2201,11 @@ DEF_TRAVERSE_STMT(CXXThisExpr, {})
DEF_TRAVERSE_STMT(CXXThrowExpr, {})
DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
+DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {})
DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
DEF_TRAVERSE_STMT(GNUNullExpr, {})
DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
+DEF_TRAVERSE_STMT(NoInitExpr, {})
DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
@@ -2356,6 +2355,9 @@ DEF_TRAVERSE_STMT(OMPBarrierDirective,
DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPFlushDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index f176e5479e1e..6b6ac3f7d5a5 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -178,7 +178,12 @@ public:
OBJC_TQ_Out = 0x4,
OBJC_TQ_Bycopy = 0x8,
OBJC_TQ_Byref = 0x10,
- OBJC_TQ_Oneway = 0x20
+ OBJC_TQ_Oneway = 0x20,
+
+ /// The nullability qualifier is set when the nullability of the
+ /// result or parameter was expressed via a context-sensitive
+ /// keyword.
+ OBJC_TQ_CSNullability = 0x40
};
protected:
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 537ad4640c24..08451c051b57 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1440,7 +1440,7 @@ public:
///
/// \returns true if this class is derived from \p Base, false otherwise.
///
- /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
+ /// \todo add a separate parameter to configure IsDerivedFrom, rather than
/// tangling input and output in \p Paths
bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const;
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 4a5b4f3d0756..c3fb57770245 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -141,7 +141,7 @@ private:
// NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
/// in, inout, etc.
- unsigned objcDeclQualifier : 6;
+ unsigned objcDeclQualifier : 7;
/// \brief Indicates whether this method has a related result type.
unsigned RelatedResultType : 1;
@@ -2203,13 +2203,17 @@ public:
OBJC_PR_atomic = 0x100,
OBJC_PR_weak = 0x200,
OBJC_PR_strong = 0x400,
- OBJC_PR_unsafe_unretained = 0x800
+ OBJC_PR_unsafe_unretained = 0x800,
+ /// Indicates that the nullability of the type was spelled with a
+ /// property attribute rather than a type qualifier.
+ OBJC_PR_nullability = 0x1000,
+ OBJC_PR_null_resettable = 0x2000
// Adding a property should change NumPropertyAttrsBits
};
enum {
/// \brief Number of bits fitting all the property attributes.
- NumPropertyAttrsBits = 12
+ NumPropertyAttrsBits = 14
};
enum SetterKind { Assign, Retain, Copy, Weak };
@@ -2217,7 +2221,8 @@ public:
private:
SourceLocation AtLoc; // location of \@property
SourceLocation LParenLoc; // location of '(' starting attribute list or null.
- TypeSourceInfo *DeclType;
+ QualType DeclType;
+ TypeSourceInfo *DeclTypeSourceInfo;
unsigned PropertyAttributes : NumPropertyAttrsBits;
unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
// \@required/\@optional
@@ -2232,12 +2237,13 @@ private:
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
SourceLocation AtLocation, SourceLocation LParenLocation,
- TypeSourceInfo *T)
+ QualType T, TypeSourceInfo *TSI,
+ PropertyControl propControl)
: NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
- LParenLoc(LParenLocation), DeclType(T),
+ LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
PropertyAttributes(OBJC_PR_noattr),
PropertyAttributesAsWritten(OBJC_PR_noattr),
- PropertyImplementation(None),
+ PropertyImplementation(propControl),
GetterName(Selector()),
SetterName(Selector()),
GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
@@ -2248,7 +2254,8 @@ public:
SourceLocation L,
IdentifierInfo *Id, SourceLocation AtLocation,
SourceLocation LParenLocation,
- TypeSourceInfo *T,
+ QualType T,
+ TypeSourceInfo *TSI,
PropertyControl propControl = None);
static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2259,9 +2266,14 @@ public:
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- TypeSourceInfo *getTypeSourceInfo() const { return DeclType; }
- QualType getType() const { return DeclType->getType(); }
- void setType(TypeSourceInfo *T) { DeclType = T; }
+ TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; }
+
+ QualType getType() const { return DeclType; }
+
+ void setType(QualType T, TypeSourceInfo *TSI) {
+ DeclType = T;
+ DeclTypeSourceInfo = TSI;
+ }
PropertyAttributeKind getPropertyAttributes() const {
return PropertyAttributeKind(PropertyAttributes);
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 90cfb2049173..0fc9b4947d49 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -217,6 +217,88 @@ public:
}
};
+void *allocateDefaultArgStorageChain(const ASTContext &C);
+
+/// Storage for a default argument. This is conceptually either empty, or an
+/// argument value, or a pointer to a previous declaration that had a default
+/// argument.
+///
+/// However, this is complicated by modules: while we require all the default
+/// arguments for a template to be equivalent, there may be more than one, and
+/// we need to track all the originating parameters to determine if the default
+/// argument is visible.
+template<typename ParmDecl, typename ArgType>
+class DefaultArgStorage {
+ /// Storage for both the value *and* another parameter from which we inherit
+ /// the default argument. This is used when multiple default arguments for a
+ /// parameter are merged together from different modules.
+ struct Chain {
+ ParmDecl *PrevDeclWithDefaultArg;
+ ArgType Value;
+ };
+ static_assert(sizeof(Chain) == sizeof(void *) * 2,
+ "non-pointer argument type?");
+
+ llvm::PointerUnion3<ArgType, ParmDecl*, Chain*> ValueOrInherited;
+
+ static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
+ const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
+ if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl*>())
+ Parm = Prev;
+ assert(!Parm->getDefaultArgStorage()
+ .ValueOrInherited.template is<ParmDecl *>() &&
+ "should only be one level of indirection");
+ return Parm;
+ }
+
+public:
+ DefaultArgStorage() : ValueOrInherited(ArgType()) {}
+
+ /// Determine whether there is a default argument for this parameter.
+ bool isSet() const { return !ValueOrInherited.isNull(); }
+ /// Determine whether the default argument for this parameter was inherited
+ /// from a previous declaration of the same entity.
+ bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
+ /// Get the default argument's value. This does not consider whether the
+ /// default argument is visible.
+ ArgType get() const {
+ const DefaultArgStorage *Storage = this;
+ if (auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl*>())
+ Storage = &Prev->getDefaultArgStorage();
+ if (auto *C = Storage->ValueOrInherited.template dyn_cast<Chain*>())
+ return C->Value;
+ return Storage->ValueOrInherited.template get<ArgType>();
+ }
+ /// Get the parameter from which we inherit the default argument, if any.
+ /// This is the parameter on which the default argument was actually written.
+ const ParmDecl *getInheritedFrom() const {
+ if (auto *D = ValueOrInherited.template dyn_cast<ParmDecl*>())
+ return D;
+ if (auto *C = ValueOrInherited.template dyn_cast<Chain*>())
+ return C->PrevDeclWithDefaultArg;
+ return nullptr;
+ }
+ /// Set the default argument.
+ void set(ArgType Arg) {
+ assert(!isSet() && "default argument already set");
+ ValueOrInherited = Arg;
+ }
+ /// Set that the default argument was inherited from another parameter.
+ void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
+ assert(!isInherited() && "default argument already inherited");
+ InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
+ if (!isSet())
+ ValueOrInherited = InheritedFrom;
+ else
+ ValueOrInherited = new (allocateDefaultArgStorageChain(C))
+ Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
+ }
+ /// Remove the default argument, even if it was inherited.
+ void clear() {
+ ValueOrInherited = ArgType();
+ }
+};
+
//===----------------------------------------------------------------------===//
// Kinds of Templates
//===----------------------------------------------------------------------===//
@@ -942,18 +1024,16 @@ class TemplateTypeParmDecl : public TypeDecl {
/// If false, it was declared with the 'class' keyword.
bool Typename : 1;
- /// \brief Whether this template type parameter inherited its
- /// default argument.
- bool InheritedDefault : 1;
-
/// \brief The default template argument, if any.
- TypeSourceInfo *DefaultArgument;
+ typedef DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *>
+ DefArgStorage;
+ DefArgStorage DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
bool Typename)
: TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
- InheritedDefault(false), DefaultArgument() { }
+ DefaultArgument() { }
/// Sema creates these on the stack during auto type deduction.
friend class Sema;
@@ -974,35 +1054,45 @@ public:
/// If not, it was declared with the 'class' keyword.
bool wasDeclaredWithTypename() const { return Typename; }
+ const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
+
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const { return DefaultArgument != nullptr; }
+ bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
/// \brief Retrieve the default argument, if any.
- QualType getDefaultArgument() const { return DefaultArgument->getType(); }
+ QualType getDefaultArgument() const {
+ return DefaultArgument.get()->getType();
+ }
/// \brief Retrieves the default argument's source information, if any.
- TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
+ TypeSourceInfo *getDefaultArgumentInfo() const {
+ return DefaultArgument.get();
+ }
/// \brief Retrieves the location of the default argument declaration.
SourceLocation getDefaultArgumentLoc() const;
/// \brief Determines whether the default argument was inherited
/// from a previous declaration of this template.
- bool defaultArgumentWasInherited() const { return InheritedDefault; }
+ bool defaultArgumentWasInherited() const {
+ return DefaultArgument.isInherited();
+ }
- /// \brief Set the default argument for this template parameter, and
- /// whether that default argument was inherited from another
- /// declaration.
- void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
- DefaultArgument = DefArg;
- InheritedDefault = Inherited;
+ /// \brief Set the default argument for this template parameter.
+ void setDefaultArgument(TypeSourceInfo *DefArg) {
+ DefaultArgument.set(DefArg);
+ }
+ /// \brief Set that this default argument was inherited from another
+ /// parameter.
+ void setInheritedDefaultArgument(const ASTContext &C,
+ TemplateTypeParmDecl *Prev) {
+ DefaultArgument.setInherited(C, Prev);
}
/// \brief Removes the default argument of this template parameter.
void removeDefaultArgument() {
- DefaultArgument = nullptr;
- InheritedDefault = false;
+ DefaultArgument.clear();
}
/// \brief Set whether this template type parameter was declared with
@@ -1034,7 +1124,8 @@ class NonTypeTemplateParmDecl
: public DeclaratorDecl, protected TemplateParmPosition {
/// \brief The default template argument, if any, and whether or not
/// it was inherited.
- llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
+ typedef DefaultArgStorage<NonTypeTemplateParmDecl, Expr*> DefArgStorage;
+ DefArgStorage DefaultArgument;
// FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
// down here to save memory.
@@ -1055,9 +1146,8 @@ class NonTypeTemplateParmDecl
IdentifierInfo *Id, QualType T,
bool ParameterPack, TypeSourceInfo *TInfo)
: DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
- TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
- ParameterPack(ParameterPack), ExpandedParameterPack(false),
- NumExpandedTypes(0)
+ TemplateParmPosition(D, P), ParameterPack(ParameterPack),
+ ExpandedParameterPack(false), NumExpandedTypes(0)
{ }
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
@@ -1097,16 +1187,14 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
+ const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
+
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const {
- return DefaultArgumentAndInherited.getPointer() != nullptr;
- }
+ bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
/// \brief Retrieve the default argument, if any.
- Expr *getDefaultArgument() const {
- return DefaultArgumentAndInherited.getPointer();
- }
+ Expr *getDefaultArgument() const { return DefaultArgument.get(); }
/// \brief Retrieve the location of the default argument, if any.
SourceLocation getDefaultArgumentLoc() const;
@@ -1114,22 +1202,20 @@ public:
/// \brief Determines whether the default argument was inherited
/// from a previous declaration of this template.
bool defaultArgumentWasInherited() const {
- return DefaultArgumentAndInherited.getInt();
+ return DefaultArgument.isInherited();
}
/// \brief Set the default argument for this template parameter, and
/// whether that default argument was inherited from another
/// declaration.
- void setDefaultArgument(Expr *DefArg, bool Inherited) {
- DefaultArgumentAndInherited.setPointer(DefArg);
- DefaultArgumentAndInherited.setInt(Inherited);
+ void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); }
+ void setInheritedDefaultArgument(const ASTContext &C,
+ NonTypeTemplateParmDecl *Parm) {
+ DefaultArgument.setInherited(C, Parm);
}
/// \brief Removes the default argument of this template parameter.
- void removeDefaultArgument() {
- DefaultArgumentAndInherited.setPointer(nullptr);
- DefaultArgumentAndInherited.setInt(false);
- }
+ void removeDefaultArgument() { DefaultArgument.clear(); }
/// \brief Whether this parameter is a non-type template parameter pack.
///
@@ -1217,10 +1303,10 @@ class TemplateTemplateParmDecl : public TemplateDecl,
{
void anchor() override;
- /// DefaultArgument - The default template argument, if any.
- TemplateArgumentLoc DefaultArgument;
- /// Whether or not the default argument was inherited.
- bool DefaultArgumentWasInherited;
+ /// \brief The default template argument, if any.
+ typedef DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>
+ DefArgStorage;
+ DefArgStorage DefaultArgument;
/// \brief Whether this parameter is a parameter pack.
bool ParameterPack;
@@ -1237,8 +1323,7 @@ class TemplateTemplateParmDecl : public TemplateDecl,
unsigned D, unsigned P, bool ParameterPack,
IdentifierInfo *Id, TemplateParameterList *Params)
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
- TemplateParmPosition(D, P), DefaultArgument(),
- DefaultArgumentWasInherited(false), ParameterPack(ParameterPack),
+ TemplateParmPosition(D, P), ParameterPack(ParameterPack),
ExpandedParameterPack(false), NumExpandedParams(0)
{ }
@@ -1322,15 +1407,16 @@ public:
return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I];
}
+ const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
+
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const {
- return !DefaultArgument.getArgument().isNull();
- }
+ bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
/// \brief Retrieve the default argument, if any.
const TemplateArgumentLoc &getDefaultArgument() const {
- return DefaultArgument;
+ static const TemplateArgumentLoc None;
+ return DefaultArgument.isSet() ? *DefaultArgument.get() : None;
}
/// \brief Retrieve the location of the default argument, if any.
@@ -1339,22 +1425,21 @@ public:
/// \brief Determines whether the default argument was inherited
/// from a previous declaration of this template.
bool defaultArgumentWasInherited() const {
- return DefaultArgumentWasInherited;
+ return DefaultArgument.isInherited();
}
/// \brief Set the default argument for this template parameter, and
/// whether that default argument was inherited from another
/// declaration.
- void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
- DefaultArgument = DefArg;
- DefaultArgumentWasInherited = Inherited;
+ void setDefaultArgument(const ASTContext &C,
+ const TemplateArgumentLoc &DefArg);
+ void setInheritedDefaultArgument(const ASTContext &C,
+ TemplateTemplateParmDecl *Prev) {
+ DefaultArgument.setInherited(C, Prev);
}
/// \brief Removes the default argument of this template parameter.
- void removeDefaultArgument() {
- DefaultArgument = TemplateArgumentLoc();
- DefaultArgumentWasInherited = false;
- }
+ void removeDefaultArgument() { DefaultArgument.clear(); }
SourceRange getSourceRange() const override LLVM_READONLY {
SourceLocation End = getLocation();
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
index 59de104b83f9..5cae5d9eca3f 100644
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ b/include/clang/AST/EvaluatedExprVisitor.h
@@ -26,29 +26,32 @@ class ASTContext;
/// \brief Given a potentially-evaluated expression, this visitor visits all
/// of its potentially-evaluated subexpressions, recursively.
-template<typename ImplClass>
-class EvaluatedExprVisitor : public StmtVisitor<ImplClass> {
- ASTContext &Context;
-
+template<template <typename> class Ptr, typename ImplClass>
+class EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> {
+protected:
+ const ASTContext &Context;
+
public:
- explicit EvaluatedExprVisitor(ASTContext &Context) : Context(Context) { }
-
+#define PTR(CLASS) typename Ptr<CLASS>::type
+
+ explicit EvaluatedExprVisitorBase(const ASTContext &Context) : Context(Context) { }
+
// Expressions that have no potentially-evaluated subexpressions (but may have
// other sub-expressions).
- void VisitDeclRefExpr(DeclRefExpr *E) { }
- void VisitOffsetOfExpr(OffsetOfExpr *E) { }
- void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { }
- void VisitExpressionTraitExpr(ExpressionTraitExpr *E) { }
- void VisitBlockExpr(BlockExpr *E) { }
- void VisitCXXUuidofExpr(CXXUuidofExpr *E) { }
- void VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { }
-
- void VisitMemberExpr(MemberExpr *E) {
+ void VisitDeclRefExpr(PTR(DeclRefExpr) E) { }
+ void VisitOffsetOfExpr(PTR(OffsetOfExpr) E) { }
+ void VisitUnaryExprOrTypeTraitExpr(PTR(UnaryExprOrTypeTraitExpr) E) { }
+ void VisitExpressionTraitExpr(PTR(ExpressionTraitExpr) E) { }
+ void VisitBlockExpr(PTR(BlockExpr) E) { }
+ void VisitCXXUuidofExpr(PTR(CXXUuidofExpr) E) { }
+ void VisitCXXNoexceptExpr(PTR(CXXNoexceptExpr) E) { }
+
+ void VisitMemberExpr(PTR(MemberExpr) E) {
// Only the base matters.
return this->Visit(E->getBase());
}
-
- void VisitChooseExpr(ChooseExpr *E) {
+
+ void VisitChooseExpr(PTR(ChooseExpr) E) {
// Don't visit either child expression if the condition is dependent.
if (E->getCond()->isValueDependent())
return;
@@ -56,7 +59,7 @@ public:
return this->Visit(E->getChosenSubExpr());
}
- void VisitGenericSelectionExpr(GenericSelectionExpr *E) {
+ void VisitGenericSelectionExpr(PTR(GenericSelectionExpr) E) {
// The controlling expression of a generic selection is not evaluated.
// Don't visit either child expression if the condition is type-dependent.
@@ -67,23 +70,23 @@ public:
return this->Visit(E->getResultExpr());
}
- void VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+ void VisitDesignatedInitExpr(PTR(DesignatedInitExpr) E) {
// Only the actual initializer matters; the designators are all constant
// expressions.
return this->Visit(E->getInit());
}
- void VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+ void VisitCXXTypeidExpr(PTR(CXXTypeidExpr) E) {
if (E->isPotentiallyEvaluated())
return this->Visit(E->getExprOperand());
}
- void VisitCallExpr(CallExpr *CE) {
+ void VisitCallExpr(PTR(CallExpr) CE) {
if (!CE->isUnevaluatedBuiltinCall(Context))
return static_cast<ImplClass*>(this)->VisitExpr(CE);
}
- void VisitLambdaExpr(LambdaExpr *LE) {
+ void VisitLambdaExpr(PTR(LambdaExpr) LE) {
// Only visit the capture initializers, and not the body.
for (LambdaExpr::capture_init_iterator I = LE->capture_init_begin(),
E = LE->capture_init_end();
@@ -94,11 +97,31 @@ public:
/// \brief The basis case walks all of the children of the statement or
/// expression, assuming they are all potentially evaluated.
- void VisitStmt(Stmt *S) {
- for (Stmt::child_range C = S->children(); C; ++C)
+ void VisitStmt(PTR(Stmt) S) {
+ for (auto C = S->children(); C; ++C)
if (*C)
this->Visit(*C);
}
+
+#undef PTR
+};
+
+/// EvaluatedExprVisitor - This class visits 'Expr *'s
+template<typename ImplClass>
+class EvaluatedExprVisitor
+ : public EvaluatedExprVisitorBase<make_ptr, ImplClass> {
+public:
+ explicit EvaluatedExprVisitor(const ASTContext &Context) :
+ EvaluatedExprVisitorBase<make_ptr, ImplClass>(Context) { }
+};
+
+/// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
+template<typename ImplClass>
+class ConstEvaluatedExprVisitor
+ : public EvaluatedExprVisitorBase<make_const_ptr, ImplClass> {
+public:
+ explicit ConstEvaluatedExprVisitor(const ASTContext &Context) :
+ EvaluatedExprVisitorBase<make_const_ptr, ImplClass>(Context) { }
};
}
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index a3be7d06c4b1..2a5b4c0f5ed0 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -598,7 +598,7 @@ public:
/// \brief Determine whether this expression involves a call to any function
/// that is not trivial.
- bool hasNonTrivialCall(ASTContext &Ctx);
+ bool hasNonTrivialCall(const ASTContext &Ctx) const;
/// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
/// integer. This must be called on an expression that constant folds to an
@@ -2273,7 +2273,7 @@ public:
/// \brief Returns \c true if this is a call to a builtin which does not
/// evaluate side-effects within its arguments.
- bool isUnevaluatedBuiltinCall(ASTContext &Ctx) const;
+ bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const;
/// getCallReturnType - Get the return type of the call expr. This is not
/// always the type of the expr itself, if the return type is a reference
@@ -4267,6 +4267,80 @@ public:
}
};
+/// \brief Represents a place-holder for an object not to be initialized by
+/// anything.
+///
+/// This only makes sense when it appears as part of an updater of a
+/// DesignatedInitUpdateExpr (see below). The base expression of a DIUE
+/// initializes a big object, and the NoInitExpr's mark the spots within the
+/// big object not to be overwritten by the updater.
+///
+/// \see DesignatedInitUpdateExpr
+class NoInitExpr : public Expr {
+public:
+ explicit NoInitExpr(QualType ty)
+ : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary,
+ false, false, ty->isInstantiationDependentType(), false) { }
+
+ explicit NoInitExpr(EmptyShell Empty)
+ : Expr(NoInitExprClass, Empty) { }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == NoInitExprClass;
+ }
+
+ SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+
+ // Iterators
+ child_range children() { return child_range(); }
+};
+
+// In cases like:
+// struct Q { int a, b, c; };
+// Q *getQ();
+// void foo() {
+// struct A { Q q; } a = { *getQ(), .q.b = 3 };
+// }
+//
+// We will have an InitListExpr for a, with type A, and then a
+// DesignatedInitUpdateExpr for "a.q" with type Q. The "base" for this DIUE
+// is the call expression *getQ(); the "updater" for the DIUE is ".q.b = 3"
+//
+class DesignatedInitUpdateExpr : public Expr {
+ // BaseAndUpdaterExprs[0] is the base expression;
+ // BaseAndUpdaterExprs[1] is an InitListExpr overwriting part of the base.
+ Stmt *BaseAndUpdaterExprs[2];
+
+public:
+ DesignatedInitUpdateExpr(const ASTContext &C, SourceLocation lBraceLoc,
+ Expr *baseExprs, SourceLocation rBraceLoc);
+
+ explicit DesignatedInitUpdateExpr(EmptyShell Empty)
+ : Expr(DesignatedInitUpdateExprClass, Empty) { }
+
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DesignatedInitUpdateExprClass;
+ }
+
+ Expr *getBase() const { return cast<Expr>(BaseAndUpdaterExprs[0]); }
+ void setBase(Expr *Base) { BaseAndUpdaterExprs[0] = Base; }
+
+ InitListExpr *getUpdater() const {
+ return cast<InitListExpr>(BaseAndUpdaterExprs[1]);
+ }
+ void setUpdater(Expr *Updater) { BaseAndUpdaterExprs[1] = Updater; }
+
+ // Iterators
+ // children = the base and the updater
+ child_range children() {
+ return child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2);
+ }
+};
+
/// \brief Represents an implicitly-generated value initialization of
/// an object of a given type.
///
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index c8ecef8ce50c..386c8dd3ee94 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -1752,7 +1752,7 @@ public:
StmtRange children() {
return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(getFinals().end() + 2));
+ reinterpret_cast<Stmt **>(varlist_end()));
}
static bool classof(const OMPClause *T) {
@@ -1837,7 +1837,7 @@ public:
StmtRange children() {
return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end() + 1));
+ reinterpret_cast<Stmt **>(varlist_end()));
}
static bool classof(const OMPClause *T) {
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 95e0df3066b0..95d773073184 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -2234,9 +2234,11 @@ DEF_TRAVERSE_STMT(CXXThisExpr, {})
DEF_TRAVERSE_STMT(CXXThrowExpr, {})
DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
+DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {})
DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
DEF_TRAVERSE_STMT(GNUNullExpr, {})
DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
+DEF_TRAVERSE_STMT(NoInitExpr, {})
DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
@@ -2386,6 +2388,9 @@ DEF_TRAVERSE_STMT(OMPBarrierDirective,
DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPFlushDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index 5161eff0993b..63f295ddfec0 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -285,24 +285,23 @@ class OMPLoopDirective : public OMPExecutableDirective {
CalcLastIterationOffset = 3,
PreConditionOffset = 4,
CondOffset = 5,
- SeparatedCondOffset = 6,
- InitOffset = 7,
- IncOffset = 8,
+ InitOffset = 6,
+ IncOffset = 7,
// The '...End' enumerators do not correspond to child expressions - they
// specify the offset to the end (and start of the following counters/
// updates/finals arrays).
- DefaultEnd = 9,
+ DefaultEnd = 8,
// The following 7 exprs are used by worksharing loops only.
- IsLastIterVariableOffset = 9,
- LowerBoundVariableOffset = 10,
- UpperBoundVariableOffset = 11,
- StrideVariableOffset = 12,
- EnsureUpperBoundOffset = 13,
- NextLowerBoundOffset = 14,
- NextUpperBoundOffset = 15,
+ IsLastIterVariableOffset = 8,
+ LowerBoundVariableOffset = 9,
+ UpperBoundVariableOffset = 10,
+ StrideVariableOffset = 11,
+ EnsureUpperBoundOffset = 12,
+ NextLowerBoundOffset = 13,
+ NextUpperBoundOffset = 14,
// Offset to the end (and start of the following counters/updates/finals
// arrays) for worksharing loop directives.
- WorksharingEnd = 16,
+ WorksharingEnd = 15,
};
/// \brief Get the counters storage.
@@ -374,9 +373,8 @@ protected:
void setPreCond(Expr *PC) {
*std::next(child_begin(), PreConditionOffset) = PC;
}
- void setCond(Expr *Cond, Expr *SeparatedCond) {
+ void setCond(Expr *Cond) {
*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; }
@@ -435,8 +433,6 @@ public:
Expr *PreCond;
/// \brief Loop condition.
Expr *Cond;
- /// \brief A condition with 1 iteration separated.
- Expr *SeparatedCond;
/// \brief Loop iteration variable init.
Expr *Init;
/// \brief Loop increment.
@@ -467,8 +463,7 @@ public:
bool builtAll() {
return IterationVarRef != nullptr && LastIteration != nullptr &&
NumIterations != nullptr && PreCond != nullptr &&
- Cond != nullptr && SeparatedCond != nullptr && Init != nullptr &&
- Inc != nullptr;
+ Cond != nullptr && Init != nullptr && Inc != nullptr;
}
/// \brief Initialize all the fields to null.
@@ -479,7 +474,6 @@ public:
CalcLastIteration = nullptr;
PreCond = nullptr;
Cond = nullptr;
- SeparatedCond = nullptr;
Init = nullptr;
Inc = nullptr;
IL = nullptr;
@@ -519,10 +513,9 @@ public:
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 *getCond() const {
+ return const_cast<Expr *>(
+ reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
}
Expr *getInit() const {
return const_cast<Expr *>(
@@ -1462,6 +1455,53 @@ public:
}
};
+/// \brief This represents '#pragma omp taskgroup' directive.
+///
+/// \code
+/// #pragma omp taskgroup
+/// \endcode
+///
+class OMPTaskgroupDirective : 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.
+ ///
+ OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
+ StartLoc, EndLoc, 0, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPTaskgroupDirective()
+ : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
+ 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 OMPTaskgroupDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTaskgroupDirectiveClass;
+ }
+};
+
/// \brief This represents '#pragma omp flush' directive.
///
/// \code
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 8cd29b7b917e..d903b9d8cbcf 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1818,6 +1818,19 @@ public:
/// checking. Should always return true.
bool isLinkageValid() const;
+ /// Determine the nullability of the given type.
+ ///
+ /// Note that nullability is only captured as sugar within the type
+ /// system, not as part of the canonical type, so nullability will
+ /// be lost by canonicalization and desugaring.
+ Optional<NullabilityKind> getNullability(const ASTContext &context) const;
+
+ /// Determine whether the given type can have a nullability
+ /// specifier applied to it, i.e., if it is any kind of pointer type
+ /// or a dependent type that could instantiate to any kind of
+ /// pointer type.
+ bool canHaveNullability() const;
+
const char *getTypeClassName() const;
QualType getCanonicalTypeInternal() const {
@@ -3479,7 +3492,10 @@ public:
attr_ptr32,
attr_ptr64,
attr_sptr,
- attr_uptr
+ attr_uptr,
+ attr_nonnull,
+ attr_nullable,
+ attr_null_unspecified,
};
private:
@@ -3513,6 +3529,35 @@ public:
bool isCallingConv() const;
+ llvm::Optional<NullabilityKind> getImmediateNullability() const;
+
+ /// Retrieve the attribute kind corresponding to the given
+ /// nullability kind.
+ static Kind getNullabilityAttrKind(NullabilityKind kind) {
+ switch (kind) {
+ case NullabilityKind::NonNull:
+ return attr_nonnull;
+
+ case NullabilityKind::Nullable:
+ return attr_nullable;
+
+ case NullabilityKind::Unspecified:
+ return attr_null_unspecified;
+ }
+ llvm_unreachable("Unknown nullability kind.");
+ }
+
+ /// Strip off the top-level nullability annotation on the given
+ /// type, if it's there.
+ ///
+ /// \param T The type to strip. If the type is exactly an
+ /// AttributedType specifying nullability (without looking through
+ /// type sugar), the nullability is returned and this type changed
+ /// to the underlying modified type.
+ ///
+ /// \returns the top-level nullability, if present.
+ static Optional<NullabilityKind> stripOuterNullability(QualType &T);
+
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
}