summaryrefslogtreecommitdiffstats
path: root/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTContext.h40
-rw-r--r--include/clang/AST/ASTDiagnostic.h22
-rw-r--r--include/clang/AST/CanonicalType.h2
-rw-r--r--include/clang/AST/Decl.h34
-rw-r--r--include/clang/AST/DeclBase.h19
-rw-r--r--include/clang/AST/DeclCXX.h1
-rw-r--r--include/clang/AST/DeclObjC.h43
-rw-r--r--include/clang/AST/DeclTemplate.h8
-rw-r--r--include/clang/AST/DeclarationName.h3
-rw-r--r--include/clang/AST/Expr.h211
-rw-r--r--include/clang/AST/ExprCXX.h170
-rw-r--r--include/clang/AST/ExprObjC.h149
-rw-r--r--include/clang/AST/ExternalASTSource.h24
-rw-r--r--include/clang/AST/GlobalDecl.h124
-rw-r--r--include/clang/AST/NestedNameSpecifier.h12
-rw-r--r--include/clang/AST/OperationKinds.h30
-rw-r--r--include/clang/AST/ParentMap.h1
-rw-r--r--include/clang/AST/PrettyPrinter.h6
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h7
-rw-r--r--include/clang/AST/Stmt.h29
-rw-r--r--include/clang/AST/StmtObjC.h33
-rw-r--r--include/clang/AST/TemplateBase.h7
-rw-r--r--include/clang/AST/TemplateName.h110
-rw-r--r--include/clang/AST/Type.h420
24 files changed, 1301 insertions, 204 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 517c25d..1526f36 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -124,7 +124,10 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
- mutable llvm::FoldingSet<SubstTemplateTemplateParmPackStorage>
+ mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage>
+ SubstTemplateTemplateParms;
+ mutable llvm::ContextualFoldingSet<SubstTemplateTemplateParmPackStorage,
+ ASTContext&>
SubstTemplateTemplateParmPacks;
/// \brief The set of nested name specifiers.
@@ -993,6 +996,18 @@ public:
return getExtQualType(T, Qs);
}
+ /// getLifetimeQualifiedType - Returns a type with the given
+ /// lifetime qualifier.
+ QualType getLifetimeQualifiedType(QualType type,
+ Qualifiers::ObjCLifetime lifetime) {
+ assert(type.getObjCLifetime() == Qualifiers::OCL_None);
+ assert(lifetime != Qualifiers::OCL_None);
+
+ Qualifiers qs;
+ qs.addObjCLifetime(lifetime);
+ return getQualifiedType(type, qs);
+ }
+
DeclarationNameInfo getNameForTemplate(TemplateName Name,
SourceLocation NameLoc) const;
@@ -1007,6 +1022,8 @@ public:
const IdentifierInfo *Name) const;
TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
OverloadedOperatorKind Operator) const;
+ TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
+ TemplateName replacement) const;
TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
const TemplateArgument &ArgPack) const;
@@ -1044,7 +1061,9 @@ public:
/// isObjCNSObjectType - Return true if this is an NSObject object with
/// its NSObject attribute set.
- bool isObjCNSObjectType(QualType Ty) const;
+ static bool isObjCNSObjectType(QualType Ty) {
+ return Ty->isObjCNSObjectType();
+ }
//===--------------------------------------------------------------------===//
// Type Sizing and Analysis
@@ -1315,6 +1334,18 @@ public:
/// getConstantArrayElementCount - Returns number of constant array elements.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
+ /// \brief Perform adjustment on the parameter type of a function.
+ ///
+ /// This routine adjusts the given parameter type @p T to the actual
+ /// parameter type used by semantic analysis (C99 6.7.5.3p[7,8],
+ /// C++ [dcl.fct]p3). The adjusted parameter type is returned.
+ QualType getAdjustedParameterType(QualType T);
+
+ /// \brief Retrieve the parameter type as adjusted for use in the signature
+ /// of a function, decaying array and function types and removing top-level
+ /// cv-qualifiers.
+ QualType getSignatureParameterType(QualType T);
+
/// getArrayDecayedType - Return the properly qualified result of decaying the
/// specified array type to a pointer. This operation is non-trivial when
/// handling typedefs etc. The canonical type of "T" must be an array type,
@@ -1328,6 +1359,10 @@ public:
/// integer type.
QualType getPromotedIntegerType(QualType PromotableType) const;
+ /// \brief Recurses in pointer/array types until it finds an objc retainable
+ /// type and returns its ownership.
+ Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const;
+
/// \brief Whether this is a promotable bitfield reference according
/// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
///
@@ -1382,6 +1417,7 @@ public:
bool typesAreCompatible(QualType T1, QualType T2,
bool CompareUnqualified = false); // C99 6.2.7p1
+ bool propertyTypesAreCompatible(QualType, QualType);
bool typesAreBlockPointerCompatible(QualType, QualType);
bool isObjCIdType(QualType T) const {
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 1cb803a..70a548d 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -33,16 +33,18 @@ namespace clang {
/// diagnostics. It is meant to be used as the argument to
/// \c Diagnostic::SetArgToStringFn(), where the cookie is an \c ASTContext
/// pointer.
- void FormatASTNodeDiagnosticArgument(Diagnostic::ArgumentKind Kind,
- intptr_t Val,
- const char *Modifier,
- unsigned ModLen,
- const char *Argument,
- unsigned ArgLen,
- const Diagnostic::ArgumentValue *PrevArgs,
- unsigned NumPrevArgs,
- llvm::SmallVectorImpl<char> &Output,
- void *Cookie);
+ void FormatASTNodeDiagnosticArgument(
+ Diagnostic::ArgumentKind Kind,
+ intptr_t Val,
+ const char *Modifier,
+ unsigned ModLen,
+ const char *Argument,
+ unsigned ArgLen,
+ const Diagnostic::ArgumentValue *PrevArgs,
+ unsigned NumPrevArgs,
+ llvm::SmallVectorImpl<char> &Output,
+ void *Cookie,
+ llvm::SmallVectorImpl<intptr_t> &QualTypeVals);
} // end namespace clang
#endif
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 2518814..38e6b41 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -250,7 +250,6 @@ public:
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPODType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
@@ -295,6 +294,7 @@ public:
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
/// \brief Retrieve the proxy-adaptor type.
///
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index d993d34..5691e99 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -702,8 +702,12 @@ private:
/// \brief Whether this variable is the for-range-declaration in a C++0x
/// for-range statement.
unsigned CXXForRangeDecl : 1;
+
+ /// \brief Whether this variable is an ARC pseudo-__strong
+ /// variable; see isARCPseudoStrong() for details.
+ unsigned ARCPseudoStrong : 1;
};
- enum { NumVarDeclBits = 13 }; // two reserved bits for now
+ enum { NumVarDeclBits = 13 }; // one reserved bit
friend class ASTDeclReader;
friend class StmtIteratorBase;
@@ -975,6 +979,20 @@ public:
void setInit(Expr *I);
+ /// \brief Determine whether this variable is a reference that
+ /// extends the lifetime of its temporary initializer.
+ ///
+ /// A reference extends the lifetime of its temporary initializer if
+ /// it's initializer is an rvalue that would normally go out of scope
+ /// at the end of the initializer (a full expression). In such cases,
+ /// the reference itself takes ownership of the temporary, which will
+ /// be destroyed when the reference goes out of scope. For example:
+ ///
+ /// \code
+ /// const int &r = 1.0; // creates a temporary of type 'int'
+ /// \endcode
+ bool extendsLifetimeOfTemporary() const;
+
EvaluatedStmt *EnsureEvaluatedStmt() const {
EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
if (!Eval) {
@@ -1102,6 +1120,13 @@ public:
/// a C++0x for-range statement.
bool isCXXForRangeDecl() const { return VarDeclBits.CXXForRangeDecl; }
void setCXXForRangeDecl(bool FRD) { VarDeclBits.CXXForRangeDecl = FRD; }
+
+ /// \brief Determine whether this variable is an ARC pseudo-__strong
+ /// variable. A pseudo-__strong variable has a __strong-qualified
+ /// type but does not actually retain the object written into it.
+ /// Generally such variables are also 'const' for safety.
+ bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; }
+ void setARCPseudoStrong(bool ps) { VarDeclBits.ARCPseudoStrong = ps; }
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
@@ -2014,6 +2039,11 @@ public:
InitializerOrBitWidth.setPointer(BW);
InitializerOrBitWidth.setInt(1);
}
+ /// removeBitWidth - Remove the bitfield width from this member.
+ void removeBitWidth() {
+ assert(isBitField() && "no bit width to remove");
+ InitializerOrBitWidth.setPointer(0);
+ }
/// hasInClassInitializer - Determine whether this member has a C++0x in-class
/// initializer.
@@ -2956,6 +2986,8 @@ public:
bool capturesCXXThis() const { return CapturesCXXThis; }
+ bool capturesVariable(const VarDecl *var) const;
+
void setCaptures(ASTContext &Context,
const Capture *begin,
const Capture *end,
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index b5047b9..8b2ef2a 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -381,7 +381,24 @@ public:
attr_iterator attr_end() const {
return hasAttrs() ? getAttrs().end() : 0;
}
-
+
+ template <typename T>
+ void dropAttr() {
+ if (!HasAttrs) return;
+
+ AttrVec &Attrs = getAttrs();
+ for (unsigned i = 0, e = Attrs.size(); i != e; /* in loop */) {
+ if (isa<T>(Attrs[i])) {
+ Attrs.erase(Attrs.begin() + i);
+ --e;
+ }
+ else
+ ++i;
+ }
+ if (Attrs.empty())
+ HasAttrs = false;
+ }
+
template <typename T>
specific_attr_iterator<T> specific_attr_begin() const {
return specific_attr_iterator<T>(attr_begin());
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 42a12eb..dd490f4 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -19,7 +19,6 @@
#include "clang/AST/Decl.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/UnresolvedSet.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
namespace clang {
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 74ceb43..d318fc2 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -641,6 +641,18 @@ public:
return false;
}
+ /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
+ /// to be incompatible with __weak references. Returns true if it is.
+ bool isArcWeakrefUnavailable() const {
+ const ObjCInterfaceDecl *Class = this;
+ while (Class) {
+ if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
+ return true;
+ Class = Class->getSuperClass();
+ }
+ return false;
+ }
+
ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
ObjCInterfaceDecl *&ClassDeclared);
ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
@@ -1240,6 +1252,9 @@ class ObjCImplementationDecl : public ObjCImplDecl {
/// IvarInitializers - The arguments used to initialize the ivars
CXXCtorInitializer **IvarInitializers;
unsigned NumIvarInitializers;
+
+ /// true if class has a .cxx_[construct,destruct] method.
+ bool HasCXXStructors : 1;
/// true of class extension has at least one bitfield ivar.
bool HasSynthBitfield : 1;
@@ -1249,7 +1264,7 @@ class ObjCImplementationDecl : public ObjCImplDecl {
ObjCInterfaceDecl *superDecl)
: ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0),
- HasSynthBitfield(false) {}
+ HasCXXStructors(false), HasSynthBitfield(false) {}
public:
static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -1287,6 +1302,9 @@ public:
void setIvarInitializers(ASTContext &C,
CXXCtorInitializer ** initializers,
unsigned numInitializers);
+
+ bool hasCXXStructors() const { return HasCXXStructors; }
+ void setHasCXXStructors(bool val) { HasCXXStructors = val; }
bool hasSynthBitfield() const { return HasSynthBitfield; }
void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
@@ -1393,7 +1411,16 @@ public:
OBJC_PR_copy = 0x20,
OBJC_PR_nonatomic = 0x40,
OBJC_PR_setter = 0x80,
- OBJC_PR_atomic = 0x100
+ OBJC_PR_atomic = 0x100,
+ OBJC_PR_weak = 0x200,
+ OBJC_PR_strong = 0x400,
+ OBJC_PR_unsafe_unretained = 0x800
+ // Adding a property should change NumPropertyAttrsBits
+ };
+
+ enum {
+ /// \brief Number of bits fitting all the property attributes.
+ NumPropertyAttrsBits = 12
};
enum SetterKind { Assign, Retain, Copy };
@@ -1401,8 +1428,8 @@ public:
private:
SourceLocation AtLoc; // location of @property
TypeSourceInfo *DeclType;
- unsigned PropertyAttributes : 9;
- unsigned PropertyAttributesAsWritten : 9;
+ unsigned PropertyAttributes : NumPropertyAttrsBits;
+ unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
// @required/@optional
unsigned PropertyImplementation : 2;
@@ -1445,6 +1472,12 @@ public:
PropertyAttributeKind getPropertyAttributesAsWritten() const {
return PropertyAttributeKind(PropertyAttributesAsWritten);
}
+
+ bool hasWrittenStorageAttribute() const {
+ return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy |
+ OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong |
+ OBJC_PR_weak);
+ }
void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
PropertyAttributesAsWritten = PRVal;
@@ -1466,7 +1499,7 @@ public:
/// the property setter. This is only valid if the property has been
/// defined to have a setter.
SetterKind getSetterKind() const {
- if (PropertyAttributes & OBJC_PR_retain)
+ if (PropertyAttributes & (OBJC_PR_retain|OBJC_PR_strong))
return Retain;
if (PropertyAttributes & OBJC_PR_copy)
return Copy;
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index dc50d61..d2b1d39 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -314,6 +314,10 @@ public:
return (TemplateSpecializationKind)(Template.getInt() + 1);
}
+ bool isExplicitSpecialization() const {
+ return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
+ }
+
/// \brief Set the template specialization kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
assert(TSK != TSK_Undeclared &&
@@ -1398,6 +1402,10 @@ public:
return static_cast<TemplateSpecializationKind>(SpecializationKind);
}
+ bool isExplicitSpecialization() const {
+ return getSpecializationKind() == TSK_ExplicitSpecialization;
+ }
+
void setSpecializationKind(TemplateSpecializationKind TSK) {
SpecializationKind = TSK;
}
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index e54719b..bb09831 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -492,6 +492,9 @@ public:
LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
}
+ /// \brief Determine whether this name involves a template parameter.
+ bool isInstantiationDependent() const;
+
/// \brief Determine whether this name contains an unexpanded
/// parameter pack.
bool containsUnexpandedParameterPack() const;
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index ce86458e..c7f8707 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -57,9 +57,12 @@ class Expr : public Stmt {
protected:
Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK,
- bool TD, bool VD, bool ContainsUnexpandedParameterPack) : Stmt(SC) {
+ bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack)
+ : Stmt(SC)
+ {
ExprBits.TypeDependent = TD;
ExprBits.ValueDependent = VD;
+ ExprBits.InstantiationDependent = ID;
ExprBits.ValueKind = VK;
ExprBits.ObjectKind = OK;
ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
@@ -95,7 +98,11 @@ public:
bool isValueDependent() const { return ExprBits.ValueDependent; }
/// \brief Set whether this expression is value-dependent or not.
- void setValueDependent(bool VD) { ExprBits.ValueDependent = VD; }
+ void setValueDependent(bool VD) {
+ ExprBits.ValueDependent = VD;
+ if (VD)
+ ExprBits.InstantiationDependent = true;
+ }
/// isTypeDependent - Determines whether this expression is
/// type-dependent (C++ [temp.dep.expr]), which means that its type
@@ -111,7 +118,37 @@ public:
bool isTypeDependent() const { return ExprBits.TypeDependent; }
/// \brief Set whether this expression is type-dependent or not.
- void setTypeDependent(bool TD) { ExprBits.TypeDependent = TD; }
+ void setTypeDependent(bool TD) {
+ ExprBits.TypeDependent = TD;
+ if (TD)
+ ExprBits.InstantiationDependent = true;
+ }
+
+ /// \brief Whether this expression is instantiation-dependent, meaning that
+ /// it depends in some way on a template parameter, even if neither its type
+ /// nor (constant) value can change due to the template instantiation.
+ ///
+ /// In the following example, the expression \c sizeof(sizeof(T() + T())) is
+ /// instantiation-dependent (since it involves a template parameter \c T), but
+ /// is neither type- nor value-dependent, since the type of the inner
+ /// \c sizeof is known (\c std::size_t) and therefore the size of the outer
+ /// \c sizeof is known.
+ ///
+ /// \code
+ /// template<typename T>
+ /// void f(T x, T y) {
+ /// sizeof(sizeof(T() + T());
+ /// }
+ /// \endcode
+ ///
+ bool isInstantiationDependent() const {
+ return ExprBits.InstantiationDependent;
+ }
+
+ /// \brief Set whether this expression is instantiation-dependent or not.
+ void setInstantiationDependent(bool ID) {
+ ExprBits.InstantiationDependent = ID;
+ }
/// \brief Whether this expression contains an unexpanded parameter
/// pack (for C++0x variadic templates).
@@ -501,6 +538,14 @@ public:
/// the rules of C++ [expr.unary.noexcept].
CanThrowResult CanThrow(ASTContext &C) const;
+ /// IgnoreImpCasts - Skip past any implicit casts which might
+ /// surround this expression. Only skips ImplicitCastExprs.
+ Expr *IgnoreImpCasts();
+
+ /// IgnoreImplicit - Skip past any implicit AST nodes which might
+ /// surround this expression.
+ Expr *IgnoreImplicit() { return cast<Expr>(Stmt::IgnoreImplicit()); }
+
/// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return
/// its subexpression. If that subexpression is also a ParenExpr,
/// then this method recursively returns its subexpression, and so forth.
@@ -555,7 +600,10 @@ public:
/// \brief Whether this expression is an implicit reference to 'this' in C++.
bool isImplicitCXXThis() const;
-
+
+ const Expr *IgnoreImpCasts() const {
+ return const_cast<Expr*>(this)->IgnoreImpCasts();
+ }
const Expr *IgnoreParens() const {
return const_cast<Expr*>(this)->IgnoreParens();
}
@@ -595,7 +643,9 @@ public:
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
ExprObjectKind OK = OK_Ordinary)
: Expr(OpaqueValueExprClass, T, VK, OK,
- T->isDependentType(), T->isDependentType(), false),
+ T->isDependentType(), T->isDependentType(),
+ T->isInstantiationDependentType(),
+ false),
SourceExpr(0), Loc(Loc) {
}
@@ -664,7 +714,8 @@ struct ExplicitTemplateArgumentList {
void initializeFrom(const TemplateArgumentListInfo &List);
void initializeFrom(const TemplateArgumentListInfo &List,
- bool &Dependent, bool &ContainsUnexpandedParameterPack);
+ bool &Dependent, bool &InstantiationDependent,
+ bool &ContainsUnexpandedParameterPack);
void copyInto(TemplateArgumentListInfo &List) const;
static std::size_t sizeFor(unsigned NumTemplateArgs);
static std::size_t sizeFor(const TemplateArgumentListInfo &List);
@@ -746,9 +797,10 @@ class DeclRefExpr : public Expr {
void computeDependence();
public:
- DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L)
- : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false),
- D(D), Loc(L) {
+ DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L,
+ const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
+ : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
+ D(D), Loc(L), DNLoc(LocInfo) {
DeclRefExprBits.HasQualifier = 0;
DeclRefExprBits.HasExplicitTemplateArgs = 0;
DeclRefExprBits.HasFoundDecl = 0;
@@ -936,6 +988,7 @@ 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) {}
@@ -1023,7 +1076,7 @@ public:
IntegerLiteral(ASTContext &C, const llvm::APInt &V,
QualType type, SourceLocation l)
: Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
- false),
+ false, false),
Loc(l) {
assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
assert(V.getBitWidth() == C.getIntWidth(type) &&
@@ -1066,7 +1119,7 @@ public:
// type should be IntTy
CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l)
: Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
- false),
+ false, false),
Value(value), Loc(l), IsWide(iswide) {
}
@@ -1101,7 +1154,7 @@ class FloatingLiteral : public Expr {
FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact,
QualType Type, SourceLocation L)
: Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false,
- false),
+ false, false),
IsExact(isexact), Loc(L) {
setValue(C, V);
}
@@ -1152,7 +1205,7 @@ class ImaginaryLiteral : public Expr {
public:
ImaginaryLiteral(Expr *val, QualType Ty)
: Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false),
+ false, false),
Val(val) {}
/// \brief Build an empty imaginary literal.
@@ -1200,21 +1253,20 @@ class StringLiteral : public Expr {
SourceLocation TokLocs[1];
StringLiteral(QualType Ty) :
- Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false) {}
+ Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false,
+ false) {}
public:
/// This is the "fully general" constructor that allows representation of
/// strings formed from multiple concatenated tokens.
- static StringLiteral *Create(ASTContext &C, const char *StrData,
- unsigned ByteLength, bool Wide, bool Pascal,
- QualType Ty,
+ static StringLiteral *Create(ASTContext &C, llvm::StringRef Str, bool Wide,
+ bool Pascal, QualType Ty,
const SourceLocation *Loc, unsigned NumStrs);
/// Simple constructor for string literals made from one token.
- static StringLiteral *Create(ASTContext &C, const char *StrData,
- unsigned ByteLength, bool Wide,
+ static StringLiteral *Create(ASTContext &C, llvm::StringRef Str, bool Wide,
bool Pascal, QualType Ty, SourceLocation Loc) {
- return Create(C, StrData, ByteLength, Wide, Pascal, Ty, &Loc, 1);
+ return Create(C, Str, Wide, Pascal, Ty, &Loc, 1);
}
/// \brief Construct an empty string literal.
@@ -1289,6 +1341,7 @@ public:
: Expr(ParenExprClass, val->getType(),
val->getValueKind(), val->getObjectKind(),
val->isTypeDependent(), val->isValueDependent(),
+ val->isInstantiationDependent(),
val->containsUnexpandedParameterPack()),
L(l), R(r), Val(val) {}
@@ -1345,6 +1398,8 @@ public:
: Expr(UnaryOperatorClass, type, VK, OK,
input->isTypeDependent() || type->isDependentType(),
input->isValueDependent(),
+ (input->isInstantiationDependent() ||
+ type->isInstantiationDependentType()),
input->containsUnexpandedParameterPack()),
Opc(opc), Loc(l), Val(input) {}
@@ -1640,6 +1695,7 @@ public:
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
TInfo->getType()->isDependentType(),
+ TInfo->getType()->isInstantiationDependentType(),
TInfo->getType()->containsUnexpandedParameterPack()),
Kind(ExprKind), isType(true), OpLoc(op), RParenLoc(rp) {
Argument.Ty = TInfo;
@@ -1652,6 +1708,7 @@ public:
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
E->isTypeDependent(),
+ E->isInstantiationDependent(),
E->containsUnexpandedParameterPack()),
Kind(ExprKind), isType(false), OpLoc(op), RParenLoc(rp) {
Argument.Ex = E;
@@ -1729,6 +1786,8 @@ public:
: Expr(ArraySubscriptExprClass, t, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(),
+ (lhs->isInstantiationDependent() ||
+ rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())),
RBracketLoc(rbracketloc) {
@@ -1986,7 +2045,9 @@ public:
const DeclarationNameInfo &NameInfo, QualType ty,
ExprValueKind VK, ExprObjectKind OK)
: Expr(MemberExprClass, ty, VK, OK,
- base->isTypeDependent(), base->isValueDependent(),
+ base->isTypeDependent(),
+ base->isValueDependent(),
+ base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()),
MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow),
@@ -2003,6 +2064,7 @@ public:
ExprValueKind VK, ExprObjectKind OK)
: Expr(MemberExprClass, ty, VK, OK,
base->isTypeDependent(), base->isValueDependent(),
+ base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(),
IsArrow(isarrow),
@@ -2188,6 +2250,8 @@ public:
: Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary,
tinfo->getType()->isDependentType(),
init->isValueDependent(),
+ (init->isInstantiationDependent() ||
+ tinfo->getType()->isInstantiationDependentType()),
init->containsUnexpandedParameterPack()),
LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {}
@@ -2276,6 +2340,9 @@ private:
case CK_IntegralComplexToReal:
case CK_IntegralComplexCast:
case CK_IntegralComplexToFloatingComplex:
+ case CK_ObjCProduceObject:
+ case CK_ObjCConsumeObject:
+ case CK_ObjCReclaimReturnedObject:
assert(!getType()->isBooleanType() && "unheralded conversion to bool");
// fallthrough to check for null base path
@@ -2318,6 +2385,8 @@ protected:
// 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->containsUnexpandedParameterPack())),
Op(op) {
@@ -2426,6 +2495,13 @@ public:
static bool classof(const ImplicitCastExpr *) { return true; }
};
+inline Expr *Expr::IgnoreImpCasts() {
+ Expr *e = this;
+ while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
+ e = ice->getSubExpr();
+ return e;
+}
+
/// ExplicitCastExpr - An explicit cast written in the source
/// code.
///
@@ -2551,6 +2627,8 @@ public:
: Expr(BinaryOperatorClass, ResTy, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(),
+ (lhs->isInstantiationDependent() ||
+ rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())),
Opc(opc), OpLoc(opLoc) {
@@ -2653,6 +2731,8 @@ protected:
: Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(),
+ (lhs->isInstantiationDependent() ||
+ rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())),
Opc(opc), OpLoc(opLoc) {
@@ -2713,11 +2793,11 @@ class AbstractConditionalOperator : public Expr {
protected:
AbstractConditionalOperator(StmtClass SC, QualType T,
ExprValueKind VK, ExprObjectKind OK,
- bool TD, bool VD,
+ bool TD, bool VD, bool ID,
bool ContainsUnexpandedParameterPack,
SourceLocation qloc,
SourceLocation cloc)
- : Expr(SC, T, VK, OK, TD, VD, ContainsUnexpandedParameterPack),
+ : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack),
QuestionLoc(qloc), ColonLoc(cloc) {}
AbstractConditionalOperator(StmtClass SC, EmptyShell Empty)
@@ -2765,6 +2845,9 @@ public:
(lhs->isTypeDependent() || rhs->isTypeDependent()),
(cond->isValueDependent() || lhs->isValueDependent() ||
rhs->isValueDependent()),
+ (cond->isInstantiationDependent() ||
+ lhs->isInstantiationDependent() ||
+ rhs->isInstantiationDependent()),
(cond->containsUnexpandedParameterPack() ||
lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack()),
@@ -2833,6 +2916,8 @@ public:
: AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK,
(common->isTypeDependent() || rhs->isTypeDependent()),
(common->isValueDependent() || rhs->isValueDependent()),
+ (common->isInstantiationDependent() ||
+ rhs->isInstantiationDependent()),
(common->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack()),
qloc, cloc),
@@ -2914,7 +2999,8 @@ class AddrLabelExpr : public Expr {
public:
AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L,
QualType t)
- : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false),
+ : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false,
+ false),
AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
/// \brief Build an empty address of a label expression.
@@ -2953,10 +3039,12 @@ class StmtExpr : public Expr {
SourceLocation LParenLoc, RParenLoc;
public:
// FIXME: Does type-dependence need to be computed differently?
+ // FIXME: Do we need to compute instantiation instantiation-dependence for
+ // statements? (ugh!)
StmtExpr(CompoundStmt *substmt, QualType T,
SourceLocation lp, SourceLocation rp) :
Expr(StmtExprClass, T, VK_RValue, OK_Ordinary,
- T->isDependentType(), false, false),
+ T->isDependentType(), false, false, false),
SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
/// \brief Build an empty statement expression.
@@ -3073,6 +3161,9 @@ public:
QualType t, ExprValueKind VK, ExprObjectKind OK,
SourceLocation RP, bool TypeDependent, bool ValueDependent)
: Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent,
+ (cond->isInstantiationDependent() ||
+ lhs->isInstantiationDependent() ||
+ rhs->isInstantiationDependent()),
(cond->containsUnexpandedParameterPack() ||
lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())),
@@ -3134,7 +3225,8 @@ class GNUNullExpr : public Expr {
public:
GNUNullExpr(QualType Ty, SourceLocation Loc)
- : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false),
+ : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false,
+ false),
TokenLoc(Loc) { }
/// \brief Build an empty GNU __null expression.
@@ -3166,6 +3258,8 @@ public:
SourceLocation RPLoc, QualType t)
: Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary,
t->isDependentType(), false,
+ (TInfo->getType()->isInstantiationDependentType() ||
+ e->isInstantiationDependent()),
(TInfo->getType()->containsUnexpandedParameterPack() ||
e->containsUnexpandedParameterPack())),
Val(e), TInfo(TInfo),
@@ -3537,9 +3631,9 @@ public:
bool isArrayDesignator() const { return Kind == ArrayDesignator; }
bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
- IdentifierInfo * getFieldName();
+ IdentifierInfo *getFieldName() const;
- FieldDecl *getField() {
+ FieldDecl *getField() const {
assert(Kind == FieldDesignator && "Only valid on a field designator");
if (Field.NameOrField & 0x01)
return 0;
@@ -3612,12 +3706,18 @@ public:
unsigned size() const { return NumDesignators; }
// Iterator access to the designators.
- typedef Designator* designators_iterator;
+ typedef Designator *designators_iterator;
designators_iterator designators_begin() { return Designators; }
designators_iterator designators_end() {
return Designators + NumDesignators;
}
+ typedef const Designator *const_designators_iterator;
+ const_designators_iterator designators_begin() const { return Designators; }
+ const_designators_iterator designators_end() const {
+ return Designators + NumDesignators;
+ }
+
typedef std::reverse_iterator<designators_iterator>
reverse_designators_iterator;
reverse_designators_iterator designators_rbegin() {
@@ -3627,6 +3727,15 @@ public:
return reverse_designators_iterator(designators_begin());
}
+ typedef std::reverse_iterator<const_designators_iterator>
+ const_reverse_designators_iterator;
+ const_reverse_designators_iterator designators_rbegin() const {
+ return const_reverse_designators_iterator(designators_end());
+ }
+ const_reverse_designators_iterator designators_rend() const {
+ return const_reverse_designators_iterator(designators_begin());
+ }
+
Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; }
void setDesignators(ASTContext &C, const Designator *Desigs,
@@ -3708,7 +3817,7 @@ class ImplicitValueInitExpr : public Expr {
public:
explicit ImplicitValueInitExpr(QualType ty)
: Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary,
- false, false, false) { }
+ false, false, ty->isInstantiationDependentType(), false) { }
/// \brief Construct an empty implicit value initialization.
explicit ImplicitValueInitExpr(EmptyShell Empty)
@@ -3735,7 +3844,7 @@ class ParenListExpr : public Expr {
public:
ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs,
- unsigned numexprs, SourceLocation rparenloc);
+ unsigned numexprs, SourceLocation rparenloc, QualType T);
/// \brief Build an empty paren list.
explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
@@ -3909,6 +4018,7 @@ public:
: Expr(ExtVectorElementExprClass, ty, VK,
(VK == VK_RValue ? OK_Ordinary : OK_VectorComponent),
base->isTypeDependent(), base->isValueDependent(),
+ base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
Base(base), Accessor(&accessor), AccessorLoc(loc) {}
@@ -3963,7 +4073,10 @@ protected:
public:
BlockExpr(BlockDecl *BD, QualType ty)
: Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary,
- ty->isDependentType(), false, false),
+ ty->isDependentType(), false,
+ // FIXME: Check for instantiate-dependence in the statement?
+ ty->isInstantiationDependentType(),
+ false),
TheBlock(BD) {}
/// \brief Build an empty block expression.
@@ -4037,26 +4150,36 @@ public:
/// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2]
/// This AST node provides support for reinterpreting a type to another
/// type of the same size.
-class AsTypeExpr : public Expr {
+class AsTypeExpr : public Expr { // Should this be an ExplicitCastExpr?
private:
- Expr* SrcExpr;
- QualType DstType;
+ Stmt *SrcExpr;
SourceLocation BuiltinLoc, RParenLoc;
+
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {}
public:
AsTypeExpr(Expr* SrcExpr, QualType DstType,
ExprValueKind VK, ExprObjectKind OK,
SourceLocation BuiltinLoc, SourceLocation RParenLoc)
- : Expr(AsTypeExprClass, DstType, VK, OK, false, false, false),
- SrcExpr(SrcExpr), DstType(DstType),
- BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
-
- /// \brief Build an empty __builtin_astype
- explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {}
+ : Expr(AsTypeExprClass, DstType, VK, OK,
+ DstType->isDependentType(),
+ DstType->isDependentType() || SrcExpr->isValueDependent(),
+ (DstType->isInstantiationDependentType() ||
+ SrcExpr->isInstantiationDependent()),
+ (DstType->containsUnexpandedParameterPack() ||
+ SrcExpr->containsUnexpandedParameterPack())),
+ SrcExpr(SrcExpr), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
/// getSrcExpr - Return the Expr to be converted.
- Expr *getSrcExpr() const { return SrcExpr; }
- QualType getDstType() const { return DstType; }
+ Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
+
+ /// getBuiltinLoc - Return the location of the __builtin_astype token.
+ SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+
+ /// getRParenLoc - Return the location of final right parenthesis.
+ SourceLocation getRParenLoc() const { return RParenLoc; }
SourceRange getSourceRange() const {
return SourceRange(BuiltinLoc, RParenLoc);
@@ -4068,7 +4191,7 @@ public:
static bool classof(const AsTypeExpr *) { return true; }
// Iterators
- child_range children() { return child_range(); }
+ child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
};
} // end namespace clang
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index a970579..1911704 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -330,7 +330,7 @@ class CXXBoolLiteralExpr : public Expr {
public:
CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false),
+ false, false),
Value(val), Loc(l) {}
explicit CXXBoolLiteralExpr(EmptyShell Empty)
@@ -359,7 +359,7 @@ class CXXNullPtrLiteralExpr : public Expr {
public:
CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false),
+ false, false),
Loc(l) {}
explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
@@ -395,6 +395,7 @@ public:
false,
// typeid is value-dependent if the type or expression are dependent
Operand->getType()->isDependentType(),
+ Operand->getType()->isInstantiationDependentType(),
Operand->getType()->containsUnexpandedParameterPack()),
Operand(Operand), Range(R) { }
@@ -404,6 +405,7 @@ public:
false,
// typeid is value-dependent if the type or expression are dependent
Operand->isTypeDependent() || Operand->isValueDependent(),
+ Operand->isInstantiationDependent(),
Operand->containsUnexpandedParameterPack()),
Operand(Operand), Range(R) { }
@@ -471,12 +473,14 @@ public:
CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
: Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
false, Operand->getType()->isDependentType(),
+ Operand->getType()->isInstantiationDependentType(),
Operand->getType()->containsUnexpandedParameterPack()),
Operand(Operand), Range(R) { }
CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R)
: Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
false, Operand->isTypeDependent(),
+ Operand->isInstantiationDependent(),
Operand->containsUnexpandedParameterPack()),
Operand(Operand), Range(R) { }
@@ -552,6 +556,7 @@ public:
// 'this' is type-dependent if the class type of the enclosing
// member function is dependent (C++ [temp.dep.expr]p2)
Type->isDependentType(), Type->isDependentType(),
+ Type->isInstantiationDependentType(),
/*ContainsUnexpandedParameterPack=*/false),
Loc(L), Implicit(isImplicit) { }
@@ -581,23 +586,35 @@ public:
class CXXThrowExpr : public Expr {
Stmt *Op;
SourceLocation ThrowLoc;
+ /// \brief Whether the thrown variable (if any) is in scope.
+ unsigned IsThrownVariableInScope : 1;
+
+ friend class ASTStmtReader;
+
public:
// Ty is the void type which is used as the result type of the
// exepression. The l is the location of the throw keyword. expr
// can by null, if the optional expression to throw isn't present.
- CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) :
+ CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l,
+ bool IsThrownVariableInScope) :
Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
+ expr && expr->isInstantiationDependent(),
expr && expr->containsUnexpandedParameterPack()),
- Op(expr), ThrowLoc(l) {}
+ Op(expr), ThrowLoc(l), IsThrownVariableInScope(IsThrownVariableInScope) {}
CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
- void setSubExpr(Expr *E) { Op = E; }
SourceLocation getThrowLoc() const { return ThrowLoc; }
- void setThrowLoc(SourceLocation L) { ThrowLoc = L; }
+ /// \brief Determines whether the variable thrown by this expression (if any!)
+ /// is within the innermost try block.
+ ///
+ /// This information is required to determine whether the NRVO can apply to
+ /// this variable.
+ bool isThrownVariableInScope() const { return IsThrownVariableInScope; }
+
SourceRange getSourceRange() const {
if (getSubExpr() == 0)
return SourceRange(ThrowLoc, ThrowLoc);
@@ -636,14 +653,14 @@ class CXXDefaultArgExpr : public Expr {
? param->getType().getNonReferenceType()
: param->getDefaultArg()->getType(),
param->getDefaultArg()->getValueKind(),
- param->getDefaultArg()->getObjectKind(), false, false, false),
+ param->getDefaultArg()->getObjectKind(), false, false, false, false),
Param(param, false), Loc(Loc) { }
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
Expr *SubExpr)
: Expr(SC, SubExpr->getType(),
SubExpr->getValueKind(), SubExpr->getObjectKind(),
- false, false, false),
+ false, false, false, false),
Param(param, true), Loc(Loc) {
*reinterpret_cast<Expr **>(this + 1) = SubExpr;
}
@@ -742,6 +759,7 @@ class CXXBindTemporaryExpr : public Expr {
: Expr(CXXBindTemporaryExprClass, SubExpr->getType(),
VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(),
SubExpr->isValueDependent(),
+ SubExpr->isInstantiationDependent(),
SubExpr->containsUnexpandedParameterPack()),
Temp(temp), SubExpr(SubExpr) { }
@@ -995,7 +1013,7 @@ public:
TypeSourceInfo *TypeInfo,
SourceLocation rParenLoc ) :
Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
- false, false, false),
+ false, false, Type->isInstantiationDependentType(), false),
RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
explicit CXXScalarValueInitExpr(EmptyShell Shell)
@@ -1241,6 +1259,7 @@ public:
bool arrayFormAsWritten, bool usualArrayDeleteWantsSize,
FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc)
: Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false,
+ arg->isInstantiationDependent(),
arg->containsUnexpandedParameterPack()),
GlobalDelete(globalDelete),
ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
@@ -1500,6 +1519,7 @@ public:
SourceLocation rparen, QualType ty)
: Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
false, queried->getType()->isDependentType(),
+ queried->getType()->isInstantiationDependentType(),
queried->getType()->containsUnexpandedParameterPack()),
UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { }
@@ -1558,6 +1578,8 @@ public:
: Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false,
lhsType->getType()->isDependentType() ||
rhsType->getType()->isDependentType(),
+ (lhsType->getType()->isInstantiationDependentType() ||
+ rhsType->getType()->isInstantiationDependentType()),
(lhsType->getType()->containsUnexpandedParameterPack() ||
rhsType->getType()->containsUnexpandedParameterPack())),
BTT(btt), Value(value), Loc(loc), RParen(rparen),
@@ -1625,6 +1647,8 @@ public:
Expr *dimension, SourceLocation rparen, QualType ty)
: Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
false, queried->getType()->isDependentType(),
+ (queried->getType()->isInstantiationDependentType() ||
+ (dimension && dimension->isInstantiationDependent())),
queried->getType()->containsUnexpandedParameterPack()),
ATT(att), Value(value), Dimension(dimension),
Loc(loc), RParen(rparen), QueriedType(queried) { }
@@ -1684,6 +1708,7 @@ public:
false, // Not type-dependent
// Value-dependent if the argument is type-dependent.
queried->isTypeDependent(),
+ queried->isInstantiationDependent(),
queried->containsUnexpandedParameterPack()),
ET(et), Value(value), Loc(loc), RParen(rparen), QueriedExpression(queried) { }
@@ -1736,8 +1761,9 @@ protected:
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
- bool KnownDependent = false,
- bool KnownContainsUnexpandedParameterPack = false);
+ bool KnownDependent,
+ bool KnownInstantiationDependent,
+ bool KnownContainsUnexpandedParameterPack);
OverloadExpr(StmtClass K, EmptyShell Empty)
: Expr(K, Empty), Results(0), NumResults(0),
@@ -1880,7 +1906,7 @@ class UnresolvedLookupExpr : public OverloadExpr {
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
bool StdIsAssociatedNamespace)
: OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo,
- TemplateArgs, Begin, End),
+ TemplateArgs, Begin, End, false, false, false),
RequiresADL(RequiresADL),
StdIsAssociatedNamespace(StdIsAssociatedNamespace),
Overloaded(Overloaded), NamingClass(NamingClass)
@@ -2727,6 +2753,7 @@ public:
: Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
/*TypeDependent*/false,
/*ValueDependent*/Val == CT_Dependent,
+ Val == CT_Dependent || Operand->isInstantiationDependent(),
Operand->containsUnexpandedParameterPack()),
Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen)
{ }
@@ -2787,7 +2814,8 @@ public:
llvm::Optional<unsigned> NumExpansions)
: Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
Pattern->getObjectKind(), /*TypeDependent=*/true,
- /*ValueDependent=*/true, /*ContainsUnexpandedParameterPack=*/false),
+ /*ValueDependent=*/true, /*InstantiationDependent=*/true,
+ /*ContainsUnexpandedParameterPack=*/false),
EllipsisLoc(EllipsisLoc),
NumExpansions(NumExpansions? *NumExpansions + 1 : 0),
Pattern(Pattern) { }
@@ -2874,6 +2902,7 @@ public:
SourceLocation PackLoc, SourceLocation RParenLoc)
: Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
/*TypeDependent=*/false, /*ValueDependent=*/true,
+ /*InstantiationDependent=*/true,
/*ContainsUnexpandedParameterPack=*/false),
OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
Length(0), Pack(Pack) { }
@@ -2885,6 +2914,7 @@ public:
unsigned Length)
: Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
/*TypeDependent=*/false, /*ValueDependent=*/false,
+ /*InstantiationDependent=*/false,
/*ContainsUnexpandedParameterPack=*/false),
OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
Length(Length), Pack(Pack) { }
@@ -2927,6 +2957,53 @@ public:
child_range children() { return child_range(); }
};
+/// \brief Represents a reference to a non-type template parameter
+/// that has been substituted with a template argument.
+class SubstNonTypeTemplateParmExpr : public Expr {
+ /// \brief The replaced parameter.
+ NonTypeTemplateParmDecl *Param;
+
+ /// \brief The replacement expression.
+ Stmt *Replacement;
+
+ /// \brief The location of the non-type template parameter reference.
+ SourceLocation NameLoc;
+
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
+ : Expr(SubstNonTypeTemplateParmExprClass, Empty) { }
+
+public:
+ SubstNonTypeTemplateParmExpr(QualType type,
+ ExprValueKind valueKind,
+ SourceLocation loc,
+ NonTypeTemplateParmDecl *param,
+ Expr *replacement)
+ : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary,
+ replacement->isTypeDependent(), replacement->isValueDependent(),
+ replacement->isInstantiationDependent(),
+ replacement->containsUnexpandedParameterPack()),
+ Param(param), Replacement(replacement), NameLoc(loc) {}
+
+ SourceLocation getNameLoc() const { return NameLoc; }
+ SourceRange getSourceRange() const { return NameLoc; }
+
+ Expr *getReplacement() const { return cast<Expr>(Replacement); }
+
+ NonTypeTemplateParmDecl *getParameter() const { return Param; }
+
+ static bool classof(const Stmt *s) {
+ return s->getStmtClass() == SubstNonTypeTemplateParmExprClass;
+ }
+ static bool classof(const SubstNonTypeTemplateParmExpr *) {
+ return true;
+ }
+
+ // Iterators
+ child_range children() { return child_range(&Replacement, &Replacement+1); }
+};
+
/// \brief Represents a reference to a non-type template parameter pack that
/// has been substituted with a non-template argument pack.
///
@@ -2953,8 +3030,10 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
/// \brief The location of the non-type template parameter pack reference.
SourceLocation NameLoc;
+ friend class ASTReader;
friend class ASTStmtReader;
- friend class ASTStmtWriter;
+ explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
+ : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { }
public:
SubstNonTypeTemplateParmPackExpr(QualType T,
@@ -2962,9 +3041,6 @@ public:
SourceLocation NameLoc,
const TemplateArgument &ArgPack);
- SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { }
-
/// \brief Retrieve the non-type template parameter pack being substituted.
NonTypeTemplateParmDecl *getParameterPack() const { return Param; }
@@ -2987,6 +3063,66 @@ public:
// Iterators
child_range children() { return child_range(); }
};
+
+/// \brief Represents a prvalue temporary that written into memory so that
+/// a reference can bind to it.
+///
+/// Prvalue expressions are materialized when they need to have an address
+/// in memory for a reference to bind to. This happens when binding a
+/// reference to the result of a conversion, e.g.,
+///
+/// \code
+/// const int &r = 1.0;
+/// \endcode
+///
+/// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is
+/// then materialized via a \c MaterializeTemporaryExpr, and the reference
+/// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues
+/// (either an lvalue or an xvalue, depending on the kind of reference binding
+/// to it), maintaining the invariant that references always bind to glvalues.
+class MaterializeTemporaryExpr : public Expr {
+ /// \brief The temporary-generating expression whose value will be
+ /// materialized.
+ Stmt *Temporary;
+
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
+public:
+ MaterializeTemporaryExpr(QualType T, Expr *Temporary,
+ bool BoundToLvalueReference)
+ : Expr(MaterializeTemporaryExprClass, T,
+ BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
+ Temporary->isTypeDependent(), Temporary->isValueDependent(),
+ Temporary->isInstantiationDependent(),
+ Temporary->containsUnexpandedParameterPack()),
+ Temporary(Temporary) { }
+
+ MaterializeTemporaryExpr(EmptyShell Empty)
+ : Expr(MaterializeTemporaryExprClass, Empty) { }
+
+ /// \brief Retrieve the temporary-generating subexpression whose value will
+ /// be materialized into a glvalue.
+ Expr *GetTemporaryExpr() const { return reinterpret_cast<Expr *>(Temporary); }
+
+ /// \brief Determine whether this materialized temporary is bound to an
+ /// lvalue reference; otherwise, it's bound to an rvalue reference.
+ bool isBoundToLvalueReference() const {
+ return getValueKind() == VK_LValue;
+ }
+
+ SourceRange getSourceRange() const { return Temporary->getSourceRange(); }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == MaterializeTemporaryExprClass;
+ }
+ static bool classof(const MaterializeTemporaryExpr *) {
+ return true;
+ }
+
+ // Iterators
+ child_range children() { return child_range(&Temporary, &Temporary + 1); }
+};
} // end namespace clang
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index 8163923..49d4cfe 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -30,7 +30,7 @@ class ObjCStringLiteral : public Expr {
public:
ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
: Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
- false),
+ false, false),
String(SL), AtLoc(L) {}
explicit ObjCStringLiteral(EmptyShell Empty)
: Expr(ObjCStringLiteralClass, Empty) {}
@@ -67,6 +67,7 @@ public:
: Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
EncodedType->getType()->isDependentType(),
EncodedType->getType()->isDependentType(),
+ EncodedType->getType()->isInstantiationDependentType(),
EncodedType->getType()->containsUnexpandedParameterPack()),
EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
@@ -106,7 +107,7 @@ public:
ObjCSelectorExpr(QualType T, Selector selInfo,
SourceLocation at, SourceLocation rp)
: Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
- false),
+ false, false),
SelName(selInfo), AtLoc(at), RParenLoc(rp){}
explicit ObjCSelectorExpr(EmptyShell Empty)
: Expr(ObjCSelectorExprClass, Empty) {}
@@ -146,7 +147,7 @@ public:
ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
SourceLocation at, SourceLocation rp)
: Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
- false),
+ false, false),
TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {}
explicit ObjCProtocolExpr(EmptyShell Empty)
: Expr(ObjCProtocolExprClass, Empty) {}
@@ -186,6 +187,7 @@ public:
bool arrow = false, bool freeIvar = false) :
Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
/*TypeDependent=*/false, base->isValueDependent(),
+ base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {}
@@ -248,6 +250,7 @@ public:
SourceLocation l, Expr *base)
: Expr(ObjCPropertyRefExprClass, t, VK, OK,
/*TypeDependent=*/false, base->isValueDependent(),
+ base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
PropertyOrGetter(PD, false), Setter(0),
IdLoc(l), ReceiverLoc(), Receiver(base) {
@@ -257,7 +260,7 @@ public:
ExprValueKind VK, ExprObjectKind OK,
SourceLocation l, SourceLocation sl, QualType st)
: Expr(ObjCPropertyRefExprClass, t, VK, OK,
- /*TypeDependent=*/false, false,
+ /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
st->containsUnexpandedParameterPack()),
PropertyOrGetter(PD, false), Setter(0),
IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
@@ -267,7 +270,7 @@ public:
QualType T, ExprValueKind VK, ExprObjectKind OK,
SourceLocation IdLoc, Expr *Base)
: Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
- Base->isValueDependent(),
+ Base->isValueDependent(), Base->isInstantiationDependent(),
Base->containsUnexpandedParameterPack()),
PropertyOrGetter(Getter, true), Setter(Setter),
IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
@@ -277,7 +280,7 @@ public:
QualType T, ExprValueKind VK, ExprObjectKind OK,
SourceLocation IdLoc,
SourceLocation SuperLoc, QualType SuperTy)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false),
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
PropertyOrGetter(Getter, true), Setter(Setter),
IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
}
@@ -286,7 +289,7 @@ public:
QualType T, ExprValueKind VK, ExprObjectKind OK,
SourceLocation IdLoc,
SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false),
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
PropertyOrGetter(Getter, true), Setter(Setter),
IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
}
@@ -456,7 +459,11 @@ class ObjCMessageExpr : public Expr {
///
/// When non-zero, we have a method declaration; otherwise, we just
/// have a selector.
- unsigned HasMethod : 8;
+ unsigned HasMethod : 1;
+
+ /// \brief Whether this message send is a "delegate init call",
+ /// i.e. a call of an init method on self from within an init method.
+ unsigned IsDelegateInitCall : 1;
/// \brief When the message expression is a send to 'super', this is
/// the location of the 'super' keyword.
@@ -476,7 +483,7 @@ class ObjCMessageExpr : public Expr {
ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
: Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0),
- HasMethod(0), SelectorOrMethod(0) { }
+ HasMethod(0), IsDelegateInitCall(0), SelectorOrMethod(0) { }
ObjCMessageExpr(QualType T, ExprValueKind VK,
SourceLocation LBracLoc,
@@ -807,6 +814,12 @@ public:
getArgs()[Arg] = ArgExpr;
}
+ /// isDelegateInitCall - Answers whether this message send has been
+ /// tagged as a "delegate init call", i.e. a call to a method in the
+ /// -init family on self from within an -init method implementation.
+ bool isDelegateInitCall() const { return IsDelegateInitCall; }
+ void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
+
SourceLocation getLeftLoc() const { return LBracLoc; }
SourceLocation getRightLoc() const { return RBracLoc; }
SourceLocation getSelectorLoc() const { return SelectorLoc; }
@@ -860,6 +873,7 @@ public:
ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
: Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
/*TypeDependent=*/false, base->isValueDependent(),
+ base->isInstantiationDependent(),
/*ContainsUnexpandedParameterPack=*/false),
Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
@@ -892,6 +906,123 @@ public:
child_range children() { return child_range(&Base, &Base+1); }
};
+
+/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
+/// argument by indirect copy-restore in ARC. This is used to support
+/// passing indirect arguments with the wrong lifetime, e.g. when
+/// passing the address of a __strong local variable to an 'out'
+/// parameter. This expression kind is only valid in an "argument"
+/// position to some sort of call expression.
+///
+/// The parameter must have type 'pointer to T', and the argument must
+/// have type 'pointer to U', where T and U agree except possibly in
+/// qualification. If the argument value is null, then a null pointer
+/// is passed; otherwise it points to an object A, and:
+/// 1. A temporary object B of type T is initialized, either by
+/// zero-initialization (used when initializing an 'out' parameter)
+/// or copy-initialization (used when initializing an 'inout'
+/// parameter).
+/// 2. The address of the temporary is passed to the function.
+/// 3. If the call completes normally, A is move-assigned from B.
+/// 4. Finally, A is destroyed immediately.
+///
+/// Currently 'T' must be a retainable object lifetime and must be
+/// __autoreleasing; this qualifier is ignored when initializing
+/// the value.
+class ObjCIndirectCopyRestoreExpr : public Expr {
+ Stmt *Operand;
+
+ // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
+
+ friend class ASTReader;
+ friend class ASTStmtReader;
+
+ void setShouldCopy(bool shouldCopy) {
+ ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
+ }
+
+ explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
+ : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
+
+public:
+ ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
+ : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
+ operand->isTypeDependent(), operand->isValueDependent(),
+ operand->isInstantiationDependent(),
+ operand->containsUnexpandedParameterPack()),
+ Operand(operand) {
+ setShouldCopy(shouldCopy);
+ }
+
+ Expr *getSubExpr() { return cast<Expr>(Operand); }
+ const Expr *getSubExpr() const { return cast<Expr>(Operand); }
+
+ /// shouldCopy - True if we should do the 'copy' part of the
+ /// copy-restore. If false, the temporary will be zero-initialized.
+ bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
+
+ child_range children() { return child_range(&Operand, &Operand+1); }
+
+ // Source locations are determined by the subexpression.
+ SourceRange getSourceRange() const { return Operand->getSourceRange(); }
+ SourceLocation getExprLoc() const { return getSubExpr()->getExprLoc(); }
+
+ static bool classof(const Stmt *s) {
+ return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
+ }
+ static bool classof(const ObjCIndirectCopyRestoreExpr *) { return true; }
+};
+
+/// \brief An Objective-C "bridged" cast expression, which casts between
+/// Objective-C pointers and C pointers, transferring ownership in the process.
+///
+/// \code
+/// NSString *str = (__bridge_transfer NSString *)CFCreateString();
+/// \endcode
+class ObjCBridgedCastExpr : public ExplicitCastExpr {
+ SourceLocation LParenLoc;
+ SourceLocation BridgeKeywordLoc;
+ unsigned Kind : 2;
+
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
+public:
+ ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
+ SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo,
+ Expr *Operand)
+ : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
+ CK_BitCast, Operand, 0, TSInfo),
+ LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
+
+ /// \brief Construct an empty Objective-C bridged cast.
+ explicit ObjCBridgedCastExpr(EmptyShell Shell)
+ : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
+
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Determine which kind of bridge is being performed via this cast.
+ ObjCBridgeCastKind getBridgeKind() const {
+ return static_cast<ObjCBridgeCastKind>(Kind);
+ }
+
+ /// \brief Retrieve the kind of bridge being performed as a string.
+ llvm::StringRef getBridgeKindName() const;
+
+ /// \brief The location of the bridge keyword.
+ SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(LParenLoc, getSubExpr()->getLocEnd());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCBridgedCastExprClass;
+ }
+ static bool classof(const ObjCBridgedCastExpr *) { return true; }
+
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 846813a..ef1f161 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -32,6 +32,20 @@ class Selector;
class Stmt;
class TagDecl;
+/// \brief Enumeration describing the result of loading information from
+/// an external source.
+enum ExternalLoadResult {
+ /// \brief Loading the external information has succeeded.
+ ELR_Success,
+
+ /// \brief Loading the external information has failed.
+ ELR_Failure,
+
+ /// \brief The external information has already been loaded, and therefore
+ /// no additional processing is required.
+ ELR_AlreadyLoaded
+};
+
/// \brief Abstract interface for external sources of AST nodes.
///
/// External AST sources provide AST nodes constructed from some
@@ -132,10 +146,10 @@ public:
/// declaration kind is one we are looking for. If NULL, all declarations
/// are returned.
///
- /// \return true if an error occurred
+ /// \return an indication of whether the load succeeded or failed.
///
/// The default implementation of this method is a no-op.
- virtual bool FindExternalLexicalDecls(const DeclContext *DC,
+ virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
bool (*isKindWeWant)(Decl::Kind),
llvm::SmallVectorImpl<Decl*> &Result);
@@ -143,14 +157,14 @@ public:
/// DeclContext.
///
/// \return true if an error occurred
- bool FindExternalLexicalDecls(const DeclContext *DC,
+ ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
llvm::SmallVectorImpl<Decl*> &Result) {
return FindExternalLexicalDecls(DC, 0, Result);
}
template <typename DeclTy>
- bool FindExternalLexicalDeclsBy(const DeclContext *DC,
- llvm::SmallVectorImpl<Decl*> &Result) {
+ ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC,
+ llvm::SmallVectorImpl<Decl*> &Result) {
return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
}
diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h
new file mode 100644
index 0000000..c43e44c
--- /dev/null
+++ b/include/clang/AST/GlobalDecl.h
@@ -0,0 +1,124 @@
+//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
+// together with its type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_GLOBALDECL_H
+#define LLVM_CLANG_AST_GLOBALDECL_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/ABI.h"
+
+namespace clang {
+
+/// GlobalDecl - represents a global declaration. This can either be a
+/// CXXConstructorDecl and the constructor type (Base, Complete).
+/// a CXXDestructorDecl and the destructor type (Base, Complete) or
+/// a VarDecl, a FunctionDecl or a BlockDecl.
+class GlobalDecl {
+ llvm::PointerIntPair<const Decl*, 2> Value;
+
+ void Init(const Decl *D) {
+ assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
+ assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
+
+ Value.setPointer(D);
+ }
+
+public:
+ GlobalDecl() {}
+
+ GlobalDecl(const VarDecl *D) { Init(D);}
+ GlobalDecl(const FunctionDecl *D) { Init(D); }
+ GlobalDecl(const BlockDecl *D) { Init(D); }
+ GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
+
+ GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
+ : Value(D, Type) {}
+ GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
+ : Value(D, Type) {}
+
+ GlobalDecl getCanonicalDecl() const {
+ GlobalDecl CanonGD;
+ CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
+ CanonGD.Value.setInt(Value.getInt());
+
+ return CanonGD;
+ }
+
+ const Decl *getDecl() const { return Value.getPointer(); }
+
+ CXXCtorType getCtorType() const {
+ assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
+ return static_cast<CXXCtorType>(Value.getInt());
+ }
+
+ CXXDtorType getDtorType() const {
+ assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
+ return static_cast<CXXDtorType>(Value.getInt());
+ }
+
+ friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
+ return LHS.Value == RHS.Value;
+ }
+
+ void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
+
+ static GlobalDecl getFromOpaquePtr(void *P) {
+ GlobalDecl GD;
+ GD.Value.setFromOpaqueValue(P);
+ return GD;
+ }
+
+ GlobalDecl getWithDecl(const Decl *D) {
+ GlobalDecl Result(*this);
+ Result.Value.setPointer(D);
+ return Result;
+ }
+};
+
+} // end namespace clang
+
+namespace llvm {
+ template<class> struct DenseMapInfo;
+
+ template<> struct DenseMapInfo<clang::GlobalDecl> {
+ static inline clang::GlobalDecl getEmptyKey() {
+ return clang::GlobalDecl();
+ }
+
+ static inline clang::GlobalDecl getTombstoneKey() {
+ return clang::GlobalDecl::
+ getFromOpaquePtr(reinterpret_cast<void*>(-1));
+ }
+
+ static unsigned getHashValue(clang::GlobalDecl GD) {
+ return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
+ }
+
+ static bool isEqual(clang::GlobalDecl LHS,
+ clang::GlobalDecl RHS) {
+ return LHS == RHS;
+ }
+
+ };
+
+ // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
+ // copy assignment operator, and destructor are all trivial.
+ template <>
+ struct isPodLike<clang::GlobalDecl> {
+ static const bool value = true;
+ };
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index c21c76b..018041f 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -186,6 +186,10 @@ public:
/// type or not.
bool isDependent() const;
+ /// \brief Whether this nested name specifier involves a template
+ /// parameter.
+ bool isInstantiationDependent() const;
+
/// \brief Whether this nested-name-specifier contains an unexpanded
/// parameter pack (for C++0x variadic templates).
bool containsUnexpandedParameterPack() const;
@@ -435,6 +439,14 @@ public:
/// copied.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
+ /// \brief Retrieve a nested-name-specifier with location
+ /// information based on the information in this builder. This loc
+ /// will contain references to the builder's internal data and may
+ /// be invalidated by any change to the builder.
+ NestedNameSpecifierLoc getTemporary() const {
+ return NestedNameSpecifierLoc(Representation, Buffer);
+ }
+
/// \brief Clear out this builder, and prepare it to build another
/// nested-name-specifier with source-location information.
void Clear() {
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index 35c72c4..92ff604 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -245,7 +245,22 @@ enum CastKind {
/// \brief Converts from an integral complex to a floating complex.
/// _Complex unsigned -> _Complex float
- CK_IntegralComplexToFloatingComplex
+ CK_IntegralComplexToFloatingComplex,
+
+ /// \brief Produces a retainable object pointer so that it may be
+ /// consumed, e.g. by being passed to a consuming parameter. Calls
+ /// objc_retain.
+ CK_ObjCProduceObject,
+
+ /// \brief Consumes a retainable object pointer that has just been
+ /// produced, e.g. as the return value of a retaining call. Enters
+ /// a cleanup to call objc_release at some indefinite time.
+ CK_ObjCConsumeObject,
+
+ /// \brief Reclaim a retainable object pointer object that may have
+ /// been produced and autoreleased as part of a function return
+ /// sequence.
+ CK_ObjCReclaimReturnedObject
};
#define CK_Invalid ((CastKind) -1)
@@ -284,6 +299,19 @@ enum UnaryOperatorKind {
UO_Extension // __extension__ marker.
};
+/// \brief The kind of bridging performed by the Objective-C bridge cast.
+enum ObjCBridgeCastKind {
+ /// \brief Bridging via __bridge, which does nothing but reinterpret
+ /// the bits.
+ OBC_Bridge,
+ /// \brief Bridging via __bridge_transfer, which transfers ownership of an
+ /// Objective-C pointer into ARC.
+ OBC_BridgeTransfer,
+ /// \brief Bridging via __bridge_retain, which makes an ARC object available
+ /// as a +1 C pointer.
+ OBC_BridgeRetained
+};
+
}
#endif
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
index 9ea5a09..22c1e72 100644
--- a/include/clang/AST/ParentMap.h
+++ b/include/clang/AST/ParentMap.h
@@ -32,6 +32,7 @@ public:
Stmt *getParent(Stmt*) const;
Stmt *getParentIgnoreParens(Stmt *) const;
Stmt *getParentIgnoreParenCasts(Stmt *) const;
+ Stmt *getOuterParenParent(Stmt *) const;
const Stmt *getParent(const Stmt* S) const {
return getParent(const_cast<Stmt*>(S));
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index cf5fadb..fc8ac36 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -41,7 +41,7 @@ struct PrintingPolicy {
SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false),
SuppressInitializers(false),
Dump(false), ConstantArraySizeAsWritten(false),
- AnonymousTagLocations(true) { }
+ AnonymousTagLocations(true), SuppressStrongLifetime(false) { }
/// \brief The number of spaces to use to indent each line.
unsigned Indentation : 8;
@@ -129,6 +129,10 @@ struct PrintingPolicy {
/// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just
/// prints "<anonymous>" for the name.
bool AnonymousTagLocations : 1;
+
+ /// \brief When true, suppress printing of the __strong lifetime qualifier in
+ /// ARC.
+ unsigned SuppressStrongLifetime : 1;
};
} // end namespace clang
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index a8f182a..85c5c08 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1721,6 +1721,7 @@ DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
+DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, { })
DEF_TRAVERSE_STMT(CXXForRangeStmt, { })
DEF_TRAVERSE_STMT(ReturnStmt, { })
DEF_TRAVERSE_STMT(SwitchStmt, { })
@@ -1933,6 +1934,10 @@ DEF_TRAVERSE_STMT(ObjCMessageExpr, { })
DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
+DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, { })
+DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(ParenExpr, { })
DEF_TRAVERSE_STMT(ParenListExpr, { })
DEF_TRAVERSE_STMT(PredefinedExpr, { })
@@ -1973,6 +1978,8 @@ DEF_TRAVERSE_STMT(CXXNoexceptExpr, { })
DEF_TRAVERSE_STMT(PackExpansionExpr, { })
DEF_TRAVERSE_STMT(SizeOfPackExpr, { })
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { })
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { })
+DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { })
// These literals (all of them) do not need any action.
DEF_TRAVERSE_STMT(IntegerLiteral, { })
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 695fb04..bf5f383 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -154,9 +154,10 @@ protected:
unsigned ObjectKind : 2;
unsigned TypeDependent : 1;
unsigned ValueDependent : 1;
+ unsigned InstantiationDependent : 1;
unsigned ContainsUnexpandedParameterPack : 1;
};
- enum { NumExprBits = 15 };
+ enum { NumExprBits = 16 };
class DeclRefExprBitfields {
friend class DeclRefExpr;
@@ -183,6 +184,13 @@ protected:
unsigned NumPreArgs : 1;
};
+ class ObjCIndirectCopyRestoreExprBitfields {
+ friend class ObjCIndirectCopyRestoreExpr;
+ unsigned : NumExprBits;
+
+ unsigned ShouldCopy : 1;
+ };
+
union {
// FIXME: this is wasteful on 64-bit platforms.
void *Aligner;
@@ -193,6 +201,7 @@ protected:
DeclRefExprBitfields DeclRefExprBits;
CastExprBitfields CastExprBits;
CallExprBitfields CallExprBits;
+ ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
};
friend class ASTStmtReader;
@@ -284,6 +293,10 @@ public:
/// works on systems with GraphViz (Mac OS X) or dot+gv installed.
void viewAST() const;
+ /// Skip past any implicit AST nodes which might surround this
+ /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
+ Stmt *IgnoreImplicit();
+
// Implement isa<T> support.
static bool classof(const Stmt *) { return true; }
@@ -327,7 +340,7 @@ public:
/// declaration pointers) or the exact representation of the statement as
/// written in the source.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- bool Canonical);
+ bool Canonical) const;
};
/// DeclStmt - Adaptor class for mixing declarations with statements and
@@ -1458,6 +1471,10 @@ class SEHExceptStmt : public Stmt {
Expr *FilterExpr,
Stmt *Block);
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { }
+
public:
static SEHExceptStmt* Create(ASTContext &C,
SourceLocation ExceptLoc,
@@ -1492,6 +1509,10 @@ class SEHFinallyStmt : public Stmt {
SEHFinallyStmt(SourceLocation Loc,
Stmt *Block);
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { }
+
public:
static SEHFinallyStmt* Create(ASTContext &C,
SourceLocation FinallyLoc,
@@ -1530,6 +1551,10 @@ class SEHTryStmt : public Stmt {
Stmt *TryBlock,
Stmt *Handler);
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { }
+
public:
static SEHTryStmt* Create(ASTContext &C,
bool isCXXTry,
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
index 1800a71..d996fc5 100644
--- a/include/clang/AST/StmtObjC.h
+++ b/include/clang/AST/StmtObjC.h
@@ -342,6 +342,39 @@ public:
child_range children() { return child_range(&Throw, &Throw+1); }
};
+/// ObjCAutoreleasePoolStmt - This represent objective-c's
+/// @autoreleasepool Statement
+class ObjCAutoreleasePoolStmt : public Stmt {
+ Stmt *SubStmt;
+ SourceLocation AtLoc;
+public:
+ ObjCAutoreleasePoolStmt(SourceLocation atLoc,
+ Stmt *subStmt)
+ : Stmt(ObjCAutoreleasePoolStmtClass),
+ SubStmt(subStmt), AtLoc(atLoc) {}
+
+ explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) :
+ Stmt(ObjCAutoreleasePoolStmtClass, Empty) { }
+
+ const Stmt *getSubStmt() const { return SubStmt; }
+ Stmt *getSubStmt() { return SubStmt; }
+ void setSubStmt(Stmt *S) { SubStmt = S; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(AtLoc, SubStmt->getLocEnd());
+ }
+
+ SourceLocation getAtLoc() const { return AtLoc; }
+ void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCAutoreleasePoolStmtClass;
+ }
+ static bool classof(const ObjCAutoreleasePoolStmt *) { return true; }
+
+ child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 821b4fc..1c693e0 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -235,9 +235,14 @@ public:
bool isNull() const { return Kind == Null; }
/// \brief Whether this template argument is dependent on a template
- /// parameter.
+ /// parameter such that its result can change from one instantiation to
+ /// another.
bool isDependent() const;
+ /// \brief Whether this template argument is dependent on a template
+ /// parameter.
+ bool isInstantiationDependent() const;
+
/// \brief Whether this template argument contains an unexpanded
/// parameter pack.
bool containsUnexpandedParameterPack() const;
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index 1721973..a180f58 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -33,6 +33,7 @@ class OverloadedTemplateStorage;
struct PrintingPolicy;
class QualifiedTemplateName;
class NamedDecl;
+class SubstTemplateTemplateParmStorage;
class SubstTemplateTemplateParmPackStorage;
class TemplateArgument;
class TemplateDecl;
@@ -42,38 +43,49 @@ class TemplateTemplateParmDecl;
/// template names or an already-substituted template template parameter pack.
class UncommonTemplateNameStorage {
protected:
+ enum Kind {
+ Overloaded,
+ SubstTemplateTemplateParm,
+ SubstTemplateTemplateParmPack
+ };
+
union {
struct {
- /// \brief If true, this is an OverloadedTemplateStorage instance;
- /// otherwise, it's a SubstTemplateTemplateParmPackStorage instance.
- unsigned IsOverloadedStorage : 1;
+ /// \brief A Kind.
+ unsigned Kind : 2;
/// \brief The number of stored templates or template arguments,
/// depending on which subclass we have.
- unsigned Size : 31;
+ unsigned Size : 30;
} Bits;
void *PointerAlignment;
};
- UncommonTemplateNameStorage(unsigned Size, bool OverloadedStorage) {
- Bits.IsOverloadedStorage = OverloadedStorage;
- Bits.Size = Size;
+ UncommonTemplateNameStorage(Kind kind, unsigned size) {
+ Bits.Kind = kind;
+ Bits.Size = size;
}
public:
unsigned size() const { return Bits.Size; }
OverloadedTemplateStorage *getAsOverloadedStorage() {
- return Bits.IsOverloadedStorage
+ return Bits.Kind == Overloaded
? reinterpret_cast<OverloadedTemplateStorage *>(this)
: 0;
}
+ SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
+ return Bits.Kind == SubstTemplateTemplateParm
+ ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
+ : 0;
+ }
+
SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
- return Bits.IsOverloadedStorage
- ? 0
- : reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this) ;
+ return Bits.Kind == SubstTemplateTemplateParmPack
+ ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
+ : 0;
}
};
@@ -82,8 +94,8 @@ public:
class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
friend class ASTContext;
- OverloadedTemplateStorage(unsigned Size)
- : UncommonTemplateNameStorage(Size, true) { }
+ OverloadedTemplateStorage(unsigned size)
+ : UncommonTemplateNameStorage(Overloaded, size) { }
NamedDecl **getStorage() {
return reinterpret_cast<NamedDecl **>(this + 1);
@@ -98,8 +110,7 @@ public:
iterator begin() const { return getStorage(); }
iterator end() const { return getStorage() + size(); }
};
-
-
+
/// \brief A structure for storing an already-substituted template template
/// parameter pack.
///
@@ -109,16 +120,14 @@ public:
class SubstTemplateTemplateParmPackStorage
: public UncommonTemplateNameStorage, public llvm::FoldingSetNode
{
- ASTContext &Context;
TemplateTemplateParmDecl *Parameter;
const TemplateArgument *Arguments;
public:
- SubstTemplateTemplateParmPackStorage(ASTContext &Context,
- TemplateTemplateParmDecl *Parameter,
+ SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
unsigned Size,
const TemplateArgument *Arguments)
- : UncommonTemplateNameStorage(Size, false), Context(Context),
+ : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
Parameter(Parameter), Arguments(Arguments) { }
/// \brief Retrieve the template template parameter pack being substituted.
@@ -130,9 +139,10 @@ public:
/// parameter was substituted.
TemplateArgument getArgumentPack() const;
- void Profile(llvm::FoldingSetNodeID &ID);
+ void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
- static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ ASTContext &Context,
TemplateTemplateParmDecl *Parameter,
const TemplateArgument &ArgPack);
};
@@ -189,6 +199,9 @@ public:
/// \brief A dependent template name that has not been resolved to a
/// template (or set of templates).
DependentTemplate,
+ /// \brief A template template parameter that has been substituted
+ /// for some other template name.
+ SubstTemplateTemplateParm,
/// \brief A template template parameter pack that has been substituted for
/// a template template argument pack, but has not yet been expanded into
/// individual arguments.
@@ -199,6 +212,7 @@ public:
explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
explicit TemplateName(OverloadedTemplateStorage *Storage)
: Storage(Storage) { }
+ explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
: Storage(Storage) { }
explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
@@ -234,6 +248,19 @@ public:
return 0;
}
+ /// \brief Retrieve the substituted template template parameter, if
+ /// known.
+ ///
+ /// \returns The storage for the substituted template template parameter,
+ /// if known. Otherwise, returns NULL.
+ SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const {
+ if (UncommonTemplateNameStorage *uncommon =
+ Storage.dyn_cast<UncommonTemplateNameStorage *>())
+ return uncommon->getAsSubstTemplateTemplateParm();
+
+ return 0;
+ }
+
/// \brief Retrieve the substituted template template parameter pack, if
/// known.
///
@@ -260,9 +287,15 @@ public:
return Storage.dyn_cast<DependentTemplateName *>();
}
+ TemplateName getUnderlying() const;
+
/// \brief Determines whether this is a dependent template name.
bool isDependent() const;
+ /// \brief Determines whether this is a template name that somehow
+ /// depends on a template parameter.
+ bool isInstantiationDependent() const;
+
/// \brief Determines whether this template name contains an
/// unexpanded parameter pack (for C++0x variadic templates).
bool containsUnexpandedParameterPack() const;
@@ -300,6 +333,41 @@ public:
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
TemplateName N);
+/// \brief A structure for storing the information associated with a
+/// substituted template template parameter.
+class SubstTemplateTemplateParmStorage
+ : public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
+ friend class ASTContext;
+
+ TemplateTemplateParmDecl *Parameter;
+ TemplateName Replacement;
+
+ SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
+ TemplateName replacement)
+ : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
+ Parameter(parameter), Replacement(replacement) {}
+
+public:
+ TemplateTemplateParmDecl *getParameter() const { return Parameter; }
+ TemplateName getReplacement() const { return Replacement; }
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ TemplateTemplateParmDecl *parameter,
+ TemplateName replacement);
+};
+
+inline TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
+ : Storage(Storage) { }
+
+inline TemplateName TemplateName::getUnderlying() const {
+ if (SubstTemplateTemplateParmStorage *subst
+ = getAsSubstTemplateTemplateParm())
+ return subst->getReplacement().getUnderlying();
+ return *this;
+}
+
/// \brief Represents a template name that was expressed as a
/// qualified name.
///
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 7763383..ef0dbda 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -126,6 +126,28 @@ public:
Strong
};
+ enum ObjCLifetime {
+ /// There is no lifetime qualification on this type.
+ OCL_None,
+
+ /// This object can be modified without requiring retains or
+ /// releases.
+ OCL_ExplicitNone,
+
+ /// Assigning into this object requires the old value to be
+ /// released and the new value to be retained. The timing of the
+ /// release of the old value is inexact: it may be moved to
+ /// immediately after the last known point where the value is
+ /// live.
+ OCL_Strong,
+
+ /// Reading or writing from this object requires a barrier call.
+ OCL_Weak,
+
+ /// Assigning into this object requires a lifetime extension.
+ OCL_Autoreleasing
+ };
+
enum {
/// The maximum supported address space number.
/// 24 bits should be enough for anyone.
@@ -218,7 +240,37 @@ public:
qs.removeObjCGCAttr();
return qs;
}
+ Qualifiers withoutObjCGLifetime() const {
+ Qualifiers qs = *this;
+ qs.removeObjCLifetime();
+ return qs;
+ }
+
+ bool hasObjCLifetime() const { return Mask & LifetimeMask; }
+ ObjCLifetime getObjCLifetime() const {
+ return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift);
+ }
+ void setObjCLifetime(ObjCLifetime type) {
+ Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift);
+ }
+ void removeObjCLifetime() { setObjCLifetime(OCL_None); }
+ void addObjCLifetime(ObjCLifetime type) {
+ assert(type);
+ setObjCLifetime(type);
+ }
+
+ /// True if the lifetime is neither None or ExplicitNone.
+ bool hasNonTrivialObjCLifetime() const {
+ ObjCLifetime lifetime = getObjCLifetime();
+ return (lifetime > OCL_ExplicitNone);
+ }
+ /// True if the lifetime is either strong or weak.
+ bool hasStrongOrWeakObjCLifetime() const {
+ ObjCLifetime lifetime = getObjCLifetime();
+ return (lifetime == OCL_Strong || lifetime == OCL_Weak);
+ }
+
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
void setAddressSpace(unsigned space) {
@@ -277,6 +329,8 @@ public:
addAddressSpace(Q.getAddressSpace());
if (Q.hasObjCGCAttr())
addObjCGCAttr(Q.getObjCGCAttr());
+ if (Q.hasObjCLifetime())
+ addObjCLifetime(Q.getObjCLifetime());
}
}
@@ -287,6 +341,8 @@ public:
!hasAddressSpace() || !qs.hasAddressSpace());
assert(getObjCGCAttr() == qs.getObjCGCAttr() ||
!hasObjCGCAttr() || !qs.hasObjCGCAttr());
+ assert(getObjCLifetime() == qs.getObjCLifetime() ||
+ !hasObjCLifetime() || !qs.hasObjCLifetime());
Mask |= qs.Mask;
}
@@ -301,10 +357,30 @@ public:
// changed.
(getObjCGCAttr() == other.getObjCGCAttr() ||
!hasObjCGCAttr() || !other.hasObjCGCAttr()) &&
+ // ObjC lifetime qualifiers must match exactly.
+ getObjCLifetime() == other.getObjCLifetime() &&
// CVR qualifiers may subset.
(((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
}
+ /// \brief Determines if these qualifiers compatibly include another set of
+ /// qualifiers from the narrow perspective of Objective-C ARC lifetime.
+ ///
+ /// One set of Objective-C lifetime qualifiers compatibly includes the other
+ /// if the lifetime qualifiers match, or if both are non-__weak and the
+ /// including set also contains the 'const' qualifier.
+ bool compatiblyIncludesObjCLifetime(Qualifiers other) const {
+ if (getObjCLifetime() == other.getObjCLifetime())
+ return true;
+
+ if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak)
+ return false;
+
+ return hasConst();
+ }
+
+ bool isSupersetOf(Qualifiers Other) const;
+
/// \brief Determine whether this set of qualifiers is a strict superset of
/// another set of qualifiers, not considering qualifier compatibility.
bool isStrictSupersetOf(Qualifiers Other) const;
@@ -351,14 +427,16 @@ public:
private:
- // bits: |0 1 2|3 .. 4|5 .. 31|
- // |C R V|GCAttr|AddrSpace|
+ // bits: |0 1 2|3 .. 4|5 .. 7|8 ... 31|
+ // |C R V|GCAttr|Lifetime|AddressSpace|
uint32_t Mask;
static const uint32_t GCAttrMask = 0x18;
static const uint32_t GCAttrShift = 3;
- static const uint32_t AddressSpaceMask = ~(CVRMask | GCAttrMask);
- static const uint32_t AddressSpaceShift = 5;
+ static const uint32_t LifetimeMask = 0xE0;
+ static const uint32_t LifetimeShift = 5;
+ static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask);
+ static const uint32_t AddressSpaceShift = 8;
};
/// CallingConv - Specifies the calling convention that a function uses.
@@ -527,6 +605,23 @@ public:
return QualType::isConstant(*this, Ctx);
}
+ /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
+ bool isPODType(ASTContext &Context) const;
+
+ /// isCXX11PODType() - Return true if this is a POD type according to the
+ /// more relaxed rules of the C++11 standard, regardless of the current
+ /// compilation's language.
+ /// (C++0x [basic.types]p9)
+ bool isCXX11PODType(ASTContext &Context) const;
+
+ /// isTrivialType - Return true if this is a trivial type
+ /// (C++0x [basic.types]p9)
+ bool isTrivialType(ASTContext &Context) const;
+
+ /// isTriviallyCopyableType - Return true if this is a trivially
+ /// copyable type (C++0x [basic.types]p9)
+ bool isTriviallyCopyableType(ASTContext &Context) const;
+
// Don't promise in the API that anything besides 'const' can be
// easily added.
@@ -546,6 +641,10 @@ public:
return withFastQualifiers(Qualifiers::Volatile);
}
+ QualType withCVRQualifiers(unsigned CVR) const {
+ return withFastQualifiers(CVR);
+ }
+
void addFastQualifiers(unsigned TQs) {
assert(!(TQs & ~Qualifiers::FastMask)
&& "non-fast qualifier bits set in mask!");
@@ -658,6 +757,13 @@ public:
return getSplitDesugaredType(*this);
}
+ /// \brief Return the specified type with one level of "sugar" removed from
+ /// the type.
+ ///
+ /// This routine takes off the first typedef, typeof, etc. If the outer level
+ /// of the type is already concrete, it returns it unmodified.
+ QualType getSingleStepDesugaredType(const ASTContext &Context) const;
+
/// IgnoreParens - Returns the specified type after dropping any
/// outer-level parentheses.
QualType IgnoreParens() const {
@@ -709,7 +815,7 @@ public:
/// getAddressSpace - Return the address space of this type.
inline unsigned getAddressSpace() const;
- /// GCAttrTypesAttr - Returns gc attribute of this type.
+ /// getObjCGCAttr - Returns gc attribute of this type.
inline Qualifiers::GC getObjCGCAttr() const;
/// isObjCGCWeak true when Type is objc's weak.
@@ -722,9 +828,24 @@ public:
return getObjCGCAttr() == Qualifiers::Strong;
}
+ /// getObjCLifetime - Returns lifetime attribute of this type.
+ Qualifiers::ObjCLifetime getObjCLifetime() const {
+ return getQualifiers().getObjCLifetime();
+ }
+
+ bool hasNonTrivialObjCLifetime() const {
+ return getQualifiers().hasNonTrivialObjCLifetime();
+ }
+
+ bool hasStrongOrWeakObjCLifetime() const {
+ return getQualifiers().hasStrongOrWeakObjCLifetime();
+ }
+
enum DestructionKind {
DK_none,
- DK_cxx_destructor
+ DK_cxx_destructor,
+ DK_objc_strong_lifetime,
+ DK_objc_weak_lifetime
};
/// isDestructedType - nonzero if objects of this type require
@@ -735,6 +856,21 @@ public:
return isDestructedTypeImpl(*this);
}
+ /// \brief Determine whether expressions of the given type are forbidden
+ /// from being lvalues in C.
+ ///
+ /// The expression types that are forbidden to be lvalues are:
+ /// - 'void', but not qualified void
+ /// - function types
+ ///
+ /// The exact rule here is C99 6.3.2.1:
+ /// An lvalue is an expression with an object type or an incomplete
+ /// type other than void.
+ bool isCForbiddenLValueType() const;
+
+ /// \brief Determine whether this type has trivial copy-assignment semantics.
+ bool hasTrivialCopyAssignment(ASTContext &Context) const;
+
private:
// These methods are implemented in a separate translation unit;
// "static"-ize them to avoid creating temporary QualTypes in the
@@ -849,6 +985,11 @@ public:
bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
+ bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); }
+ Qualifiers::ObjCLifetime getObjCLifetime() const {
+ return Quals.getObjCLifetime();
+ }
+
bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
@@ -931,6 +1072,10 @@ private:
/// subclasses can pack their bitfields into the same word.
unsigned Dependent : 1;
+ /// \brief Whether this type somehow involves a template parameter, even
+ /// if the resolution of the type does not depend on a template parameter.
+ unsigned InstantiationDependent : 1;
+
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
unsigned VariablyModified : 1;
@@ -968,7 +1113,7 @@ private:
return CachedLocalOrUnnamed;
}
};
- enum { NumTypeBits = 17 };
+ enum { NumTypeBits = 18 };
protected:
// These classes allow subclasses to somewhat cleanly pack bitfields
@@ -1111,12 +1256,14 @@ private:
protected:
// silence VC++ warning C4355: 'this' : used in base member initializer list
Type *this_() { return this; }
- Type(TypeClass tc, QualType canon, bool Dependent, bool VariablyModified,
+ Type(TypeClass tc, QualType canon, bool Dependent,
+ bool InstantiationDependent, bool VariablyModified,
bool ContainsUnexpandedParameterPack)
: ExtQualsTypeCommonBase(this,
canon.isNull() ? QualType(this_(), 0) : canon) {
TypeBits.TC = tc;
TypeBits.Dependent = Dependent;
+ TypeBits.InstantiationDependent = Dependent || InstantiationDependent;
TypeBits.VariablyModified = VariablyModified;
TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
TypeBits.CacheValidAndVisibility = 0;
@@ -1126,8 +1273,15 @@ protected:
}
friend class ASTContext;
- void setDependent(bool D = true) { TypeBits.Dependent = D; }
- void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; }
+ void setDependent(bool D = true) {
+ TypeBits.Dependent = D;
+ if (D)
+ TypeBits.InstantiationDependent = true;
+ }
+ void setInstantiationDependent(bool D = true) {
+ TypeBits.InstantiationDependent = D; }
+ void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM;
+ }
void setContainsUnexpandedParameterPack(bool PP = true) {
TypeBits.ContainsUnexpandedParameterPack = PP;
}
@@ -1186,31 +1340,14 @@ public:
return !isReferenceType() && !isFunctionType() && !isVoidType();
}
- /// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10).
- bool isPODType() const;
-
/// isLiteralType - Return true if this is a literal type
/// (C++0x [basic.types]p10)
bool isLiteralType() const;
- /// isTrivialType - Return true if this is a trivial type
- /// (C++0x [basic.types]p9)
- bool isTrivialType() const;
-
- /// isTriviallyCopyableType - Return true if this is a trivially copyable type
- /// (C++0x [basic.types]p9
- bool isTriviallyCopyableType() const;
-
/// \brief Test if this type is a standard-layout type.
/// (C++0x [basic.type]p9)
bool isStandardLayoutType() const;
- /// isCXX11PODType() - Return true if this is a POD type according to the
- /// more relaxed rules of the C++11 standard, regardless of the current
- /// compilation's language.
- /// (C++0x [basic.types]p9)
- bool isCXX11PODType() const;
-
/// Helper methods to distinguish type categories. All type predicates
/// operate on the canonical type, ignoring typedefs and qualifiers.
@@ -1290,7 +1427,11 @@ public:
bool isComplexIntegerType() const; // GCC _Complex integer type.
bool isVectorType() const; // GCC vector type.
bool isExtVectorType() const; // Extended vector type.
- bool isObjCObjectPointerType() const; // Pointer to *any* ObjC object.
+ bool isObjCObjectPointerType() const; // pointer to ObjC object
+ bool isObjCRetainableType() const; // ObjC object or block pointer
+ bool isObjCLifetimeType() const; // (array of)* retainable type
+ bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type
+ bool isObjCNSObjectType() const; // __attribute__((NSObject))
// FIXME: change this to 'raw' interface type, so we can used 'interface' type
// for the common case.
bool isObjCObjectType() const; // NSString or typeof(*(id)0)
@@ -1302,9 +1443,19 @@ public:
bool isObjCClassType() const; // Class
bool isObjCSelType() const; // Class
bool isObjCBuiltinType() const; // 'id' or 'Class'
+ bool isObjCARCBridgableType() const;
+ bool isCARCBridgableType() const;
bool isTemplateTypeParmType() const; // C++ template type parameter
bool isNullPtrType() const; // C++0x nullptr_t
+ /// Determines if this type, which must satisfy
+ /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
+ /// than implicitly __strong.
+ bool isObjCARCImplicitlyUnretainedType() const;
+
+ /// Return the implicit lifetime for this type, which must not be dependent.
+ Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const;
+
enum ScalarTypeKind {
STK_Pointer,
STK_MemberPointer,
@@ -1322,6 +1473,14 @@ public:
/// (C++ [temp.dep.type]).
bool isDependentType() const { return TypeBits.Dependent; }
+ /// \brief Determine whether this type is an instantiation-dependent type,
+ /// meaning that the type involves a template parameter (even if the
+ /// definition does not actually depend on the type substituted for that
+ /// template parameter).
+ bool isInstantiationDependentType() const {
+ return TypeBits.InstantiationDependent;
+ }
+
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
bool isVariablyModifiedType() const { return TypeBits.VariablyModified; }
@@ -1336,6 +1495,8 @@ public:
/// \brief Determine wither this type is a C++ elaborated-type-specifier.
bool isElaboratedTypeSpecifier() const;
+
+ bool canDecayToPointerType() const;
/// hasPointerRepresentation - Whether this type is represented
/// natively as a pointer; this includes pointers, references, block
@@ -1480,6 +1641,7 @@ public:
}
CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
void dump() const;
+
static bool classof(const Type *) { return true; }
friend class ASTReader;
@@ -1586,6 +1748,7 @@ public:
public:
BuiltinType(Kind K)
: Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
+ /*InstantiationDependent=*/(K == Dependent),
/*VariablyModified=*/false,
/*Unexpanded paramter pack=*/false) {
BuiltinTypeBits.Kind = K;
@@ -1631,6 +1794,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode {
QualType ElementType;
ComplexType(QualType Element, QualType CanonicalPtr) :
Type(Complex, CanonicalPtr, Element->isDependentType(),
+ Element->isInstantiationDependentType(),
Element->isVariablyModifiedType(),
Element->containsUnexpandedParameterPack()),
ElementType(Element) {
@@ -1661,6 +1825,7 @@ class ParenType : public Type, public llvm::FoldingSetNode {
ParenType(QualType InnerType, QualType CanonType) :
Type(Paren, CanonType, InnerType->isDependentType(),
+ InnerType->isInstantiationDependentType(),
InnerType->isVariablyModifiedType(),
InnerType->containsUnexpandedParameterPack()),
Inner(InnerType) {
@@ -1692,6 +1857,7 @@ class PointerType : public Type, public llvm::FoldingSetNode {
PointerType(QualType Pointee, QualType CanonicalPtr) :
Type(Pointer, CanonicalPtr, Pointee->isDependentType(),
+ Pointee->isInstantiationDependentType(),
Pointee->isVariablyModifiedType(),
Pointee->containsUnexpandedParameterPack()),
PointeeType(Pointee) {
@@ -1724,6 +1890,7 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType; // Block is some kind of pointer type
BlockPointerType(QualType Pointee, QualType CanonicalCls) :
Type(BlockPointer, CanonicalCls, Pointee->isDependentType(),
+ Pointee->isInstantiationDependentType(),
Pointee->isVariablyModifiedType(),
Pointee->containsUnexpandedParameterPack()),
PointeeType(Pointee) {
@@ -1760,6 +1927,7 @@ protected:
ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
bool SpelledAsLValue) :
Type(tc, CanonicalRef, Referencee->isDependentType(),
+ Referencee->isInstantiationDependentType(),
Referencee->isVariablyModifiedType(),
Referencee->containsUnexpandedParameterPack()),
PointeeType(Referencee)
@@ -1844,6 +2012,8 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
Type(MemberPointer, CanonicalPtr,
Cls->isDependentType() || Pointee->isDependentType(),
+ (Cls->isInstantiationDependentType() ||
+ Pointee->isInstantiationDependentType()),
Pointee->isVariablyModifiedType(),
(Cls->containsUnexpandedParameterPack() ||
Pointee->containsUnexpandedParameterPack())),
@@ -1911,6 +2081,7 @@ protected:
ArraySizeModifier sm, unsigned tq,
bool ContainsUnexpandedParameterPack)
: Type(tc, can, et->isDependentType() || tc == DependentSizedArray,
+ et->isInstantiationDependentType() || tc == DependentSizedArray,
(tc == VariableArray || et->isVariablyModifiedType()),
ContainsUnexpandedParameterPack),
ElementType(et) {
@@ -2344,28 +2515,32 @@ class FunctionType : public Type {
// you'll need to adjust both the Bits field below and
// Type::FunctionTypeBitfields.
- // | CC |noreturn|hasregparm|regparm
- // |0 .. 2| 3 | 4 |5 .. 7
+ // | CC |noreturn|produces|regparm|
+ // |0 .. 2| 3 | 4 | 5 .. 7|
+ //
+ // regparm is either 0 (no regparm attribute) or the regparm value+1.
enum { CallConvMask = 0x7 };
enum { NoReturnMask = 0x8 };
- enum { HasRegParmMask = 0x10 };
- enum { RegParmMask = ~(CallConvMask | NoReturnMask),
- RegParmOffset = 5 };
+ enum { ProducesResultMask = 0x10 };
+ enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask),
+ RegParmOffset = 5 }; // Assumed to be the last field
- unsigned char Bits;
+ uint16_t Bits;
- ExtInfo(unsigned Bits) : Bits(static_cast<unsigned char>(Bits)) {}
+ ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
friend class FunctionType;
public:
// Constructor with no defaults. Use this when you know that you
// have all the elements (when reading an AST file for example).
- ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc) {
+ ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
+ bool producesResult) {
+ assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
Bits = ((unsigned) cc) |
(noReturn ? NoReturnMask : 0) |
- (hasRegParm ? HasRegParmMask : 0) |
- (regParm << RegParmOffset);
+ (producesResult ? ProducesResultMask : 0) |
+ (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0);
}
// Constructor with all defaults. Use when for example creating a
@@ -2373,8 +2548,14 @@ class FunctionType : public Type {
ExtInfo() : Bits(0) {}
bool getNoReturn() const { return Bits & NoReturnMask; }
- bool getHasRegParm() const { return Bits & HasRegParmMask; }
- unsigned getRegParm() const { return Bits >> RegParmOffset; }
+ bool getProducesResult() const { return Bits & ProducesResultMask; }
+ bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; }
+ unsigned getRegParm() const {
+ unsigned RegParm = Bits >> RegParmOffset;
+ if (RegParm > 0)
+ --RegParm;
+ return RegParm;
+ }
CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
bool operator==(ExtInfo Other) const {
@@ -2394,8 +2575,17 @@ class FunctionType : public Type {
return ExtInfo(Bits & ~NoReturnMask);
}
+ ExtInfo withProducesResult(bool producesResult) const {
+ if (producesResult)
+ return ExtInfo(Bits | ProducesResultMask);
+ else
+ return ExtInfo(Bits & ~ProducesResultMask);
+ }
+
ExtInfo withRegParm(unsigned RegParm) const {
- return ExtInfo(HasRegParmMask | (Bits & ~RegParmMask) | (RegParm << RegParmOffset));
+ assert(RegParm < 7 && "Invalid regparm value");
+ return ExtInfo((Bits & ~RegParmMask) |
+ ((RegParm + 1) << RegParmOffset));
}
ExtInfo withCallingConv(CallingConv cc) const {
@@ -2411,9 +2601,10 @@ protected:
FunctionType(TypeClass tc, QualType res, bool variadic,
unsigned typeQuals, RefQualifierKind RefQualifier,
QualType Canonical, bool Dependent,
+ bool InstantiationDependent,
bool VariablyModified, bool ContainsUnexpandedParameterPack,
ExtInfo Info)
- : Type(tc, Canonical, Dependent, VariablyModified,
+ : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
ContainsUnexpandedParameterPack),
ResultType(res) {
FunctionTypeBits.ExtInfo = Info.Bits;
@@ -2458,7 +2649,8 @@ public:
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
: FunctionType(FunctionNoProto, Result, false, 0, RQ_None, Canonical,
- /*Dependent=*/false, Result->isVariablyModifiedType(),
+ /*Dependent=*/false, /*InstantiationDependent=*/false,
+ Result->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false, Info) {}
friend class ASTContext; // ASTContext creates these.
@@ -2495,7 +2687,8 @@ public:
struct ExtProtoInfo {
ExtProtoInfo() :
Variadic(false), ExceptionSpecType(EST_None), TypeQuals(0),
- RefQualifier(RQ_None), NumExceptions(0), Exceptions(0), NoexceptExpr(0) {}
+ RefQualifier(RQ_None), NumExceptions(0), Exceptions(0), NoexceptExpr(0),
+ ConsumedArguments(0) {}
FunctionType::ExtInfo ExtInfo;
bool Variadic;
@@ -2505,6 +2698,7 @@ public:
unsigned NumExceptions;
const QualType *Exceptions;
Expr *NoexceptExpr;
+ const bool *ConsumedArguments;
};
private:
@@ -2523,7 +2717,7 @@ private:
QualType canonical, const ExtProtoInfo &epi);
/// NumArgs - The number of arguments this function has, not counting '...'.
- unsigned NumArgs : 20;
+ unsigned NumArgs : 19;
/// NumExceptions - The number of types in the exception spec, if any.
unsigned NumExceptions : 9;
@@ -2531,6 +2725,9 @@ private:
/// ExceptionSpecType - The type of exception specification this function has.
unsigned ExceptionSpecType : 3;
+ /// HasAnyConsumedArgs - Whether this function has any consumed arguments.
+ unsigned HasAnyConsumedArgs : 1;
+
/// ArgInfo - There is an variable size array after the class in memory that
/// holds the argument types.
@@ -2540,8 +2737,25 @@ private:
/// NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing
/// to the expression in the noexcept() specifier.
+ /// ConsumedArgs - A variable size array, following Exceptions
+ /// and of length NumArgs, holding flags indicating which arguments
+ /// are consumed. This only appears if HasAnyConsumedArgs is true.
+
friend class ASTContext; // ASTContext creates these.
+ const bool *getConsumedArgsBuffer() const {
+ assert(hasAnyConsumedArgs());
+
+ // Find the end of the exceptions.
+ Expr * const *eh_end = reinterpret_cast<Expr * const *>(arg_type_end());
+ if (getExceptionSpecType() != EST_ComputedNoexcept)
+ eh_end += NumExceptions;
+ else
+ eh_end += 1; // NoexceptExpr
+
+ return reinterpret_cast<const bool*>(eh_end);
+ }
+
public:
unsigned getNumArgs() const { return NumArgs; }
QualType getArgType(unsigned i) const {
@@ -2562,6 +2776,8 @@ public:
} else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
EPI.NoexceptExpr = getNoexceptExpr();
}
+ if (hasAnyConsumedArgs())
+ EPI.ConsumedArguments = getConsumedArgsBuffer();
return EPI;
}
@@ -2647,6 +2863,16 @@ public:
return exception_begin() + NumExceptions;
}
+ bool hasAnyConsumedArgs() const {
+ return HasAnyConsumedArgs;
+ }
+ bool isArgConsumed(unsigned I) const {
+ assert(I < getNumArgs() && "argument index out of range!");
+ if (hasAnyConsumedArgs())
+ return getConsumedArgsBuffer()[I];
+ return false;
+ }
+
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2670,7 +2896,7 @@ class UnresolvedUsingType : public Type {
UnresolvedUsingTypenameDecl *Decl;
UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
- : Type(UnresolvedUsing, QualType(), true, false,
+ : Type(UnresolvedUsing, QualType(), true, true, false,
/*ContainsUnexpandedParameterPack=*/false),
Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
friend class ASTContext; // ASTContext creates these.
@@ -2700,7 +2926,9 @@ class TypedefType : public Type {
TypedefNameDecl *Decl;
protected:
TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
- : Type(tc, can, can->isDependentType(), can->isVariablyModifiedType(),
+ : Type(tc, can, can->isDependentType(),
+ can->isInstantiationDependentType(),
+ can->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false),
Decl(const_cast<TypedefNameDecl*>(D)) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
@@ -2731,7 +2959,7 @@ public:
QualType desugar() const;
/// \brief Returns whether this type directly provides sugar.
- bool isSugared() const { return true; }
+ bool isSugared() const;
static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
static bool classof(const TypeOfExprType *) { return true; }
@@ -2751,9 +2979,6 @@ public:
DependentTypeOfExprType(const ASTContext &Context, Expr *E)
: TypeOfExprType(E), Context(Context) { }
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, Context, getUnderlyingExpr());
}
@@ -2766,7 +2991,9 @@ public:
class TypeOfType : public Type {
QualType TOType;
TypeOfType(QualType T, QualType can)
- : Type(TypeOf, can, T->isDependentType(), T->isVariablyModifiedType(),
+ : Type(TypeOf, can, T->isDependentType(),
+ T->isInstantiationDependentType(),
+ T->isVariablyModifiedType(),
T->containsUnexpandedParameterPack()),
TOType(T) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
@@ -2802,10 +3029,10 @@ public:
QualType getUnderlyingType() const { return UnderlyingType; }
/// \brief Remove a single level of sugar.
- QualType desugar() const { return getUnderlyingType(); }
+ QualType desugar() const;
/// \brief Returns whether this type directly provides sugar.
- bool isSugared() const { return !isDependentType(); }
+ bool isSugared() const;
static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
static bool classof(const DecltypeType *) { return true; }
@@ -2823,9 +3050,6 @@ class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
public:
DependentDecltypeType(const ASTContext &Context, Expr *E);
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, Context, getUnderlyingExpr());
}
@@ -2971,6 +3195,7 @@ public:
// Enumerated operand (string or keyword).
attr_objc_gc,
+ attr_objc_ownership,
attr_pcs,
FirstEnumOperandKind = attr_objc_gc,
@@ -2994,6 +3219,7 @@ private:
AttributedType(QualType canon, Kind attrKind,
QualType modified, QualType equivalent)
: Type(Attributed, canon, canon->isDependentType(),
+ canon->isInstantiationDependentType(),
canon->isVariablyModifiedType(),
canon->containsUnexpandedParameterPack()),
ModifiedType(modified), EquivalentType(equivalent) {
@@ -3046,13 +3272,16 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
/// Build a non-canonical type.
TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
: Type(TemplateTypeParm, Canon, /*Dependent=*/true,
+ /*InstantiationDependent=*/true,
/*VariablyModified=*/false,
Canon->containsUnexpandedParameterPack()),
TTPDecl(TTPDecl) { }
/// Build the canonical type.
TemplateTypeParmType(unsigned D, unsigned I, bool PP)
- : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true,
+ : Type(TemplateTypeParm, QualType(this, 0),
+ /*Dependent=*/true,
+ /*InstantiationDependent=*/true,
/*VariablyModified=*/false, PP) {
CanTTPTInfo.Depth = D;
CanTTPTInfo.Index = I;
@@ -3112,6 +3341,7 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
: Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(),
+ Canon->isInstantiationDependentType(),
Canon->isVariablyModifiedType(),
Canon->containsUnexpandedParameterPack()),
Replaced(Param) { }
@@ -3211,6 +3441,7 @@ class AutoType : public Type, public llvm::FoldingSetNode {
AutoType(QualType DeducedType)
: Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
/*Dependent=*/DeducedType.isNull(),
+ /*InstantiationDependent=*/DeducedType.isNull(),
/*VariablyModified=*/false, /*ContainsParameterPack=*/false) {
assert((DeducedType.isNull() || !DeducedType->isDependentType()) &&
"deduced a dependent type for auto");
@@ -3244,28 +3475,35 @@ public:
static bool classof(const AutoType *T) { return true; }
};
-/// \brief Represents the type of a template specialization as written
-/// in the source code.
+/// \brief Represents a type template specialization; the template
+/// must be a class template, a type alias template, or a template
+/// template parameter. A template which cannot be resolved to one of
+/// these, e.g. because it is written with a dependent scope
+/// specifier, is instead represented as a
+/// @c DependentTemplateSpecializationType.
///
-/// Template specialization types represent the syntactic form of a
-/// template-id that refers to a type, e.g., @c vector<int>. Some
-/// template specialization types are syntactic sugar, whose canonical
-/// type will point to some other type node that represents the
-/// instantiation or class template specialization. For example, a
-/// class template specialization type of @c vector<int> will refer to
-/// a tag type for the instantiation
-/// @c std::vector<int, std::allocator<int>>.
+/// A non-dependent template specialization type is always "sugar",
+/// typically for a @c RecordType. For example, a class template
+/// specialization type of @c vector<int> will refer to a tag type for
+/// the instantiation @c std::vector<int, std::allocator<int>>
///
-/// Other template specialization types, for which the template name
-/// is dependent, may be canonical types. These types are always
-/// dependent.
+/// Template specializations are dependent if either the template or
+/// any of the template arguments are dependent, in which case the
+/// type may also be canonical.
///
-/// An instance of this type is followed by an array of TemplateArgument*s,
-/// then, if the template specialization type is for a type alias template,
-/// a QualType representing the non-canonical aliased type.
+/// Instances of this type are allocated with a trailing array of
+/// TemplateArguments, followed by a QualType representing the
+/// non-canonical aliased type when the template is a type alias
+/// template.
class TemplateSpecializationType
: public Type, public llvm::FoldingSetNode {
- /// \brief The name of the template being specialized.
+ /// \brief The name of the template being specialized. This is
+ /// either a TemplateName::Template (in which case it is a
+ /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a
+ /// TypeAliasTemplateDecl*), a
+ /// TemplateName::SubstTemplateTemplateParmPack, or a
+ /// TemplateName::SubstTemplateTemplateParm (in which case the
+ /// replacement must, recursively, be one of these).
TemplateName Template;
/// \brief - The number of template arguments named in this class
@@ -3283,12 +3521,15 @@ public:
/// \brief Determine whether any of the given template arguments are
/// dependent.
static bool anyDependentTemplateArguments(const TemplateArgument *Args,
- unsigned NumArgs);
+ unsigned NumArgs,
+ bool &InstantiationDependent);
static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
- unsigned NumArgs);
+ unsigned NumArgs,
+ bool &InstantiationDependent);
- static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &);
+ static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &,
+ bool &InstantiationDependent);
/// \brief Print a template argument list, including the '<' and '>'
/// enclosing the template arguments.
@@ -3399,6 +3640,7 @@ class InjectedClassNameType : public Type {
// interdependencies.
InjectedClassNameType(CXXRecordDecl *D, QualType TST)
: Type(InjectedClassName, QualType(), /*Dependent=*/true,
+ /*InstantiationDependent=*/true,
/*VariablyModified=*/false,
/*ContainsUnexpandedParameterPack=*/false),
Decl(D), InjectedType(TST) {
@@ -3461,9 +3703,10 @@ enum ElaboratedTypeKeyword {
class TypeWithKeyword : public Type {
protected:
TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
- QualType Canonical, bool Dependent, bool VariablyModified,
+ QualType Canonical, bool Dependent,
+ bool InstantiationDependent, bool VariablyModified,
bool ContainsUnexpandedParameterPack)
- : Type(tc, Canonical, Dependent, VariablyModified,
+ : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
ContainsUnexpandedParameterPack) {
TypeWithKeywordBits.Keyword = Keyword;
}
@@ -3523,6 +3766,7 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
QualType NamedType, QualType CanonType)
: TypeWithKeyword(Keyword, Elaborated, CanonType,
NamedType->isDependentType(),
+ NamedType->isInstantiationDependentType(),
NamedType->isVariablyModifiedType(),
NamedType->containsUnexpandedParameterPack()),
NNS(NNS), NamedType(NamedType) {
@@ -3585,6 +3829,7 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, QualType CanonType)
: TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true,
+ /*InstantiationDependent=*/true,
/*VariablyModified=*/false,
NNS->containsUnexpandedParameterPack()),
NNS(NNS), Name(Name) {
@@ -3738,6 +3983,7 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
PackExpansionType(QualType Pattern, QualType Canon,
llvm::Optional<unsigned> NumExpansions)
: Type(PackExpansion, Canon, /*Dependent=*/true,
+ /*InstantiationDependent=*/true,
/*VariableModified=*/Pattern->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false),
Pattern(Pattern),
@@ -3829,7 +4075,7 @@ protected:
enum Nonce_ObjCInterface { Nonce_ObjCInterface };
ObjCObjectType(enum Nonce_ObjCInterface)
- : Type(ObjCInterface, QualType(), false, false, false),
+ : Type(ObjCInterface, QualType(), false, false, false, false),
BaseType(QualType(this_(), 0)) {
ObjCObjectTypeBits.NumProtocols = 0;
}
@@ -3986,7 +4232,7 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
ObjCObjectPointerType(QualType Canonical, QualType Pointee)
- : Type(ObjCObjectPointer, Canonical, false, false, false),
+ : Type(ObjCObjectPointer, Canonical, false, false, false, false),
PointeeType(Pointee) {}
friend class ASTContext; // ASTContext creates these.
@@ -4303,6 +4549,11 @@ inline QualType QualType::getNonReferenceType() const {
return *this;
}
+inline bool QualType::isCForbiddenLValueType() const {
+ return ((getTypePtr()->isVoidType() && !hasQualifiers()) ||
+ getTypePtr()->isFunctionType());
+}
+
/// \brief Tests whether the type is categorized as a fundamental type.
///
/// \returns True for types specified in C++0x [basic.fundamental].
@@ -4480,6 +4731,11 @@ inline bool Type::isOverloadableType() const {
return isDependentType() || isRecordType() || isEnumeralType();
}
+/// \brief Determines whether this type can decay to a pointer type.
+inline bool Type::canDecayToPointerType() const {
+ return isFunctionType() || isArrayType();
+}
+
inline bool Type::hasPointerRepresentation() const {
return (isPointerType() || isReferenceType() || isBlockPointerType() ||
isObjCObjectPointerType() || isNullPtrType());
OpenPOWER on IntegriCloud