aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2011-05-02 19:39:53 +0000
committerDimitry Andric <dim@FreeBSD.org>2011-05-02 19:39:53 +0000
commit01af97d3b23bded2b2b21af19bbc6e4cce49e5b3 (patch)
tree64a10f4c4154739d4a8191d7e1b52ce497f4ebd6 /include/clang/AST
parentc3b054d250cdca485c71845089c316e10610ebad (diff)
downloadsrc-01af97d3b23bded2b2b21af19bbc6e4cce49e5b3.tar.gz
src-01af97d3b23bded2b2b21af19bbc6e4cce49e5b3.zip
Vendor import of clang trunk r130700:vendor/clang/clang-r130700
Notes
Notes: svn path=/vendor/clang/dist/; revision=221339 svn path=/vendor/clang/clang-r130700/; revision=221340; tag=vendor/clang/clang-r130700
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTConsumer.h2
-rw-r--r--include/clang/AST/ASTContext.h76
-rw-r--r--include/clang/AST/ASTDiagnostic.h3
-rw-r--r--include/clang/AST/ASTMutationListener.h13
-rw-r--r--include/clang/AST/Attr.h15
-rw-r--r--include/clang/AST/CXXInheritance.h2
-rw-r--r--include/clang/AST/CanonicalType.h3
-rw-r--r--include/clang/AST/CharUnits.h16
-rw-r--r--include/clang/AST/Decl.h555
-rw-r--r--include/clang/AST/DeclBase.h87
-rw-r--r--include/clang/AST/DeclCXX.h351
-rw-r--r--include/clang/AST/DeclFriend.h11
-rw-r--r--include/clang/AST/DeclObjC.h46
-rw-r--r--include/clang/AST/DeclTemplate.h112
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h3
-rw-r--r--include/clang/AST/Expr.h508
-rw-r--r--include/clang/AST/ExprCXX.h280
-rw-r--r--include/clang/AST/ExprObjC.h40
-rw-r--r--include/clang/AST/ExternalASTSource.h67
-rw-r--r--include/clang/AST/NestedNameSpecifier.h140
-rw-r--r--include/clang/AST/PrettyPrinter.h26
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h118
-rw-r--r--include/clang/AST/Stmt.h168
-rw-r--r--include/clang/AST/StmtCXX.h82
-rw-r--r--include/clang/AST/StmtIterator.h1
-rw-r--r--include/clang/AST/TemplateBase.h27
-rw-r--r--include/clang/AST/Type.h325
-rw-r--r--include/clang/AST/TypeLoc.h157
28 files changed, 2448 insertions, 786 deletions
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 08ee4ef40de0..fcc91768dac3 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -89,7 +89,7 @@ public:
/// \brief If the consumer is interested in entities getting modified after
/// their initial creation, it should return a pointer to
- /// a GetASTMutationListener here.
+ /// an ASTMutationListener here.
virtual ASTMutationListener *GetASTMutationListener() { return 0; }
/// \brief If the consumer is interested in entities being deserialized from
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index c0eeb5af3892..28ec8cf88d52 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -14,10 +14,12 @@
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
#define LLVM_CLANG_AST_ASTCONTEXT_H
+#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/VersionTuple.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
@@ -27,6 +29,7 @@
#include "clang/AST/UsuallyTinyPtrVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Allocator.h"
@@ -68,7 +71,7 @@ namespace clang {
class TemplateTypeParmDecl;
class TranslationUnitDecl;
class TypeDecl;
- class TypedefDecl;
+ class TypedefNameDecl;
class UsingDecl;
class UsingShadowDecl;
class UnresolvedSetIterator;
@@ -77,7 +80,7 @@ namespace clang {
/// ASTContext - This class holds long-lived AST nodes (such as types and
/// decls) that can be referred to throughout the semantic analysis of a file.
-class ASTContext {
+class ASTContext : public llvm::RefCountedBase<ASTContext> {
ASTContext &this_() { return *this; }
mutable std::vector<Type*> Types;
@@ -96,7 +99,8 @@ class ASTContext {
DependentSizedExtVectorTypes;
mutable llvm::FoldingSet<VectorType> VectorTypes;
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
- mutable llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;
+ mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
+ FunctionProtoTypes;
mutable llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
mutable llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
@@ -310,6 +314,9 @@ class ASTContext {
llvm::OwningPtr<CXXABI> ABI;
CXXABI *createCXXABI(const TargetInfo &T);
+ /// \brief The logical -> physical address space map.
+ const LangAS::Map &AddrSpaceMap;
+
friend class ASTDeclReader;
public:
@@ -335,6 +342,14 @@ public:
}
void Deallocate(void *Ptr) const { }
+ /// Return the total amount of physical memory allocated for representing
+ /// AST nodes and type information.
+ size_t getASTAllocatedMemory() const {
+ return BumpAlloc.getTotalMemory();
+ }
+ /// Return the total memory used for various side tables.
+ size_t getSideTableAllocatedMemory() const;
+
PartialDiagnostic::StorageAllocator &getDiagAllocator() {
return DiagAllocator;
}
@@ -381,6 +396,16 @@ public:
FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
+
+ /// ZeroBitfieldFollowsNonBitfield - return 'true" if 'FD' is a zero-length
+ /// bitfield which follows the non-bitfield 'LastFD'.
+ bool ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD,
+ const FieldDecl *LastFD) const;
+
+ /// ZeroBitfieldFollowsBitfield - return 'true" if 'FD' is a zero-length
+ /// bitfield which follows the bitfield 'LastFD'.
+ bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD,
+ const FieldDecl *LastFD) const;
// Access to the set of methods overridden by the given C++ method.
typedef CXXMethodVector::iterator overridden_cxx_method_iterator;
@@ -413,10 +438,13 @@ public:
CanQualType FloatTy, DoubleTy, LongDoubleTy;
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
CanQualType VoidPtrTy, NullPtrTy;
- CanQualType OverloadTy;
- CanQualType DependentTy;
+ CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
+ // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
+ mutable QualType AutoDeductTy; // Deduction against 'auto'.
+ mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'.
+
ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,
IdentifierTable &idents, SelectorTable &sels,
Builtin::Context &builtins,
@@ -654,9 +682,9 @@ public:
}
/// getTypedefType - Return the unique reference to the type for the
- /// specified typename decl.
- QualType getTypedefType(const TypedefDecl *Decl, QualType Canon = QualType())
- const;
+ /// specified typedef-name decl.
+ QualType getTypedefType(const TypedefNameDecl *Decl,
+ QualType Canon = QualType()) const;
QualType getRecordType(const RecordDecl *Decl) const;
@@ -676,7 +704,7 @@ public:
QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
bool ParameterPack,
- IdentifierInfo *Name = 0) const;
+ TemplateTypeParmDecl *ParmDecl = 0) const;
QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgument *Args,
@@ -739,6 +767,12 @@ public:
/// getAutoType - C++0x deduced auto type.
QualType getAutoType(QualType DeducedType) const;
+ /// getAutoDeductType - C++0x deduction pattern for 'auto' type.
+ QualType getAutoDeductType() const;
+
+ /// getAutoRRefDeductType - C++0x deduction pattern for 'auto &&' type.
+ QualType getAutoRRefDeductType() const;
+
/// getTagDeclType - Return the unique reference to the type for the
/// specified TagDecl (struct/union/class/enum) decl.
QualType getTagDeclType(const TagDecl *Decl) const;
@@ -1294,6 +1328,21 @@ public:
QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
QualType typeDomain) const;
+ unsigned getTargetAddressSpace(QualType T) const {
+ return getTargetAddressSpace(T.getQualifiers());
+ }
+
+ unsigned getTargetAddressSpace(Qualifiers Q) const {
+ return getTargetAddressSpace(Q.getAddressSpace());
+ }
+
+ unsigned getTargetAddressSpace(unsigned AS) const {
+ if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count)
+ return AS;
+ else
+ return AddrSpaceMap[AS - LangAS::Offset];
+ }
+
private:
// Helper for integer ordering
unsigned getIntegerRank(const Type *T) const;
@@ -1332,7 +1381,8 @@ public:
const ObjCObjectType *RHS);
bool canAssignObjCInterfacesInBlockPointer(
const ObjCObjectPointerType *LHSOPT,
- const ObjCObjectPointerType *RHSOPT);
+ const ObjCObjectPointerType *RHSOPT,
+ bool BlockReturnType);
bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
@@ -1340,7 +1390,7 @@ public:
// Functions for calculating composite types
QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false);
+ bool Unqualified = false, bool BlockReturnType = false);
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
bool Unqualified = false);
QualType mergeFunctionArgumentTypes(QualType, QualType,
@@ -1528,13 +1578,13 @@ private:
};
/// @brief Utility function for constructing a nullary selector.
-static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
+static inline Selector GetNullarySelector(llvm::StringRef name, ASTContext& Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(0, &II);
}
/// @brief Utility function for constructing an unary selector.
-static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) {
+static inline Selector GetUnarySelector(llvm::StringRef name, ASTContext& Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(1, &II);
}
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 1ab53b3e9148..1cb803a3396a 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -15,7 +15,8 @@
namespace clang {
namespace diag {
enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM,
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+ SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM,
#define ASTSTART
#include "clang/Basic/DiagnosticASTKinds.inc"
#undef DIAG
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index 01e618024913..470cca8ee76e 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -20,6 +20,8 @@ namespace clang {
class CXXRecordDecl;
class ClassTemplateDecl;
class ClassTemplateSpecializationDecl;
+ class FunctionDecl;
+ class FunctionTemplateDecl;
/// \brief An abstract interface that should be implemented by listeners
/// that want to be notified when an AST entity gets modified after its
@@ -41,6 +43,17 @@ public:
/// template declaration.
virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
const ClassTemplateSpecializationDecl *D) {}
+
+ /// \brief A template specialization (or partial one) was added to the
+ /// template declaration.
+ virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
+ const FunctionDecl *D) {}
+
+ /// \brief An implicit member got a definition.
+ virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
+
+ /// \brief A static data member was implicitly instantiated.
+ virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
};
} // end namespace clang
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 67968fde2d6b..719023926bae 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -17,9 +17,11 @@
#include "llvm/Support/Casting.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/VersionTuple.h"
#include <cassert>
#include <cstring>
#include <algorithm>
@@ -120,6 +122,19 @@ public:
static bool classof(const InheritableAttr *) { return true; }
};
+class InheritableParamAttr : public InheritableAttr {
+protected:
+ InheritableParamAttr(attr::Kind AK, SourceLocation L)
+ : InheritableAttr(AK, L) {}
+
+public:
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
+ }
+ static bool classof(const InheritableParamAttr *) { return true; }
+};
+
#include "clang/AST/Attrs.inc"
/// AttrVec - A vector of Attr, which is how they are stored on the AST.
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 2d30cb3b8b62..d712e7d0c751 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -87,7 +87,7 @@ public:
/// BasePaths - Represents the set of paths from a derived class to
/// one of its (direct or indirect) bases. For example, given the
-/// following class hierachy:
+/// following class hierarchy:
///
/// @code
/// class A { };
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 4d7fcfd1d121..b3550f877323 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -655,7 +655,8 @@ struct CanProxyAdaptor<TemplateTypeParmType>
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getName)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
};
template<>
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index cf909e88220f..d7cbd08e6c2e 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -34,7 +34,7 @@ namespace clang {
/// architectures where the two are the same size.
///
/// For portability, never assume that a target character is 8 bits wide. Use
- /// CharUnit values whereever you calculate sizes, offsets, or alignments
+ /// CharUnit values wherever you calculate sizes, offsets, or alignments
/// in character units.
class CharUnits {
public:
@@ -70,10 +70,24 @@ namespace clang {
Quantity += Other.Quantity;
return *this;
}
+ CharUnits& operator++ () {
+ ++Quantity;
+ return *this;
+ }
+ CharUnits operator++ (int) {
+ return CharUnits(Quantity++);
+ }
CharUnits& operator-= (const CharUnits &Other) {
Quantity -= Other.Quantity;
return *this;
}
+ CharUnits& operator-- () {
+ --Quantity;
+ return *this;
+ }
+ CharUnits operator-- (int) {
+ return CharUnits(Quantity--);
+ }
// Comparison operators.
bool operator== (const CharUnits &Other) const {
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 31cee24df993..ef4920520391 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -20,6 +20,7 @@
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/Basic/Linkage.h"
+#include "llvm/ADT/Optional.h"
namespace clang {
class CXXTemporary;
@@ -119,14 +120,6 @@ public:
return getIdentifier() ? getIdentifier()->getName() : "";
}
- llvm::StringRef getMessageUnavailableAttr(bool unavailable) const {
- if (!unavailable)
- return "";
- if (const UnavailableAttr *UA = getAttr<UnavailableAttr>())
- return UA->getMessage();
- return "";
- }
-
/// getNameAsString - Get a human-readable name for the declaration, even if
/// it is one of the special kinds of names (C++ constructor, Objective-C
/// selector, etc). Creating this name requires expensive string
@@ -281,6 +274,10 @@ public:
/// \brief Determines the linkage and visibility of this entity.
LinkageInfo getLinkageAndVisibility() const;
+ /// \brief If visibility was explicitly specified for this
+ /// declaration, return that visibility.
+ llvm::Optional<Visibility> getExplicitVisibility() const;
+
/// \brief Clear the linkage cache in response to a change
/// to the declaration.
void ClearLinkageCache();
@@ -310,16 +307,32 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
/// location is where the __label__ is.
class LabelDecl : public NamedDecl {
LabelStmt *TheStmt;
- LabelDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *II, LabelStmt *S)
- : NamedDecl(Label, DC, L, II), TheStmt(S) {}
-
+ /// LocStart - For normal labels, this is the same as the main declaration
+ /// label, i.e., the location of the identifier; for GNU local labels,
+ /// this is the location of the __label__ keyword.
+ SourceLocation LocStart;
+
+ LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II,
+ LabelStmt *S, SourceLocation StartL)
+ : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {}
+
public:
static LabelDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *II);
+ SourceLocation IdentL, IdentifierInfo *II);
+ static LabelDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation IdentL, IdentifierInfo *II,
+ SourceLocation GnuLabelL);
LabelStmt *getStmt() const { return TheStmt; }
void setStmt(LabelStmt *T) { TheStmt = T; }
-
+
+ bool isGnuLocal() const { return LocStart != getLocation(); }
+ void setLocStart(SourceLocation L) { LocStart = L; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(LocStart, getLocation());
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const LabelDecl *D) { return true; }
@@ -330,7 +343,11 @@ public:
class NamespaceDecl : public NamedDecl, public DeclContext {
bool IsInline : 1;
- SourceLocation LBracLoc, RBracLoc;
+ /// LocStart - The starting location of the source range, pointing
+ /// to either the namespace or the inline keyword.
+ SourceLocation LocStart;
+ /// RBraceLoc - The ending location of the source range.
+ SourceLocation RBraceLoc;
// For extended namespace definitions:
//
@@ -357,13 +374,16 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
/// namespace declaration (which the boolean indicates).
llvm::PointerIntPair<NamespaceDecl *, 1, bool> OrigOrAnonNamespace;
- NamespaceDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
- : NamedDecl(Namespace, DC, L, Id), DeclContext(Namespace),
- IsInline(false), NextNamespace(), OrigOrAnonNamespace(0, true) { }
+ NamespaceDecl(DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id)
+ : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
+ IsInline(false), LocStart(StartLoc), RBraceLoc(),
+ NextNamespace(), OrigOrAnonNamespace(0, true) { }
public:
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id);
+ SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id);
/// \brief Returns true if this is an anonymous namespace declaration.
///
@@ -427,7 +447,7 @@ public:
void setAnonymousNamespace(NamespaceDecl *D) {
assert(!D || D->isAnonymousNamespace());
- assert(!D || D->getParent() == this);
+ assert(!D || D->getParent()->getRedeclContext() == this);
getOriginalNamespace()->OrigOrAnonNamespace.setPointer(D);
}
@@ -437,14 +457,14 @@ public:
}
virtual SourceRange getSourceRange() const {
- return SourceRange(getLocation(), RBracLoc);
+ return SourceRange(LocStart, RBraceLoc);
}
- SourceLocation getLBracLoc() const { return LBracLoc; }
- SourceLocation getRBracLoc() const { return RBracLoc; }
- void setLBracLoc(SourceLocation L) { LBracLoc = L; }
- void setRBracLoc(SourceLocation R) { RBracLoc = R; }
-
+ SourceLocation getLocStart() const { return LocStart; }
+ SourceLocation getRBraceLoc() const { return RBraceLoc; }
+ void setLocStart(SourceLocation L) { LocStart = L; }
+ void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamespaceDecl *D) { return true; }
@@ -484,16 +504,24 @@ public:
/// name qualifier, to be used for the case of out-of-line declarations.
struct QualifierInfo {
NestedNameSpecifierLoc QualifierLoc;
- /// NumTemplParamLists - The number of template parameter lists
- /// that were matched against the template-ids occurring into the NNS.
+
+ /// NumTemplParamLists - The number of "outer" template parameter lists.
+ /// The count includes all of the template parameter lists that were matched
+ /// against the template-ids occurring into the NNS and possibly (in the
+ /// case of an explicit specialization) a final "template <>".
unsigned NumTemplParamLists;
+
/// TemplParamLists - A new-allocated array of size NumTemplParamLists,
- /// containing pointers to the matched template parameter lists.
+ /// containing pointers to the "outer" template parameter lists.
+ /// It includes all of the template parameter lists that were matched
+ /// against the template-ids occurring into the NNS and possibly (in the
+ /// case of an explicit specialization) a final "template <>".
TemplateParameterList** TemplParamLists;
/// Default constructor.
QualifierInfo() : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(0) {}
- /// setTemplateParameterListsInfo - Sets info about matched template
+
+ /// setTemplateParameterListsInfo - Sets info about "outer" template
/// parameter lists.
void setTemplateParameterListsInfo(ASTContext &Context,
unsigned NumTPLists,
@@ -516,14 +544,20 @@ class DeclaratorDecl : public ValueDecl {
llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
+ /// InnerLocStart - The start of the source range for this declaration,
+ /// ignoring outer template declarations.
+ SourceLocation InnerLocStart;
+
bool hasExtInfo() const { return DeclInfo.is<ExtInfo*>(); }
ExtInfo *getExtInfo() { return DeclInfo.get<ExtInfo*>(); }
const ExtInfo *getExtInfo() const { return DeclInfo.get<ExtInfo*>(); }
protected:
DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T, TypeSourceInfo *TInfo)
- : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo) {}
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ SourceLocation StartL)
+ : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) {
+ }
public:
TypeSourceInfo *getTypeSourceInfo() const {
@@ -540,14 +574,14 @@ public:
/// getInnerLocStart - Return SourceLocation representing start of source
/// range ignoring outer template declarations.
- virtual SourceLocation getInnerLocStart() const { return getLocation(); }
+ SourceLocation getInnerLocStart() const { return InnerLocStart; }
+ void setInnerLocStart(SourceLocation L) { InnerLocStart = L; }
/// getOuterLocStart - Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
- SourceRange getSourceRange() const {
- return SourceRange(getOuterLocStart(), getLocation());
- }
+
+ virtual SourceRange getSourceRange() const;
/// \brief Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
@@ -574,9 +608,7 @@ public:
return getExtInfo()->TemplParamLists[index];
}
void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
- TemplateParameterList **TPLists) {
- getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
- }
+ TemplateParameterList **TPLists);
SourceLocation getTypeSpecStartLoc() const;
@@ -650,32 +682,77 @@ protected:
mutable InitType Init;
private:
- // FIXME: This can be packed into the bitfields in Decl.
- unsigned SClass : 3;
- unsigned SClassAsWritten : 3;
- bool ThreadSpecified : 1;
- bool HasCXXDirectInit : 1;
-
- /// \brief Whether this variable is the exception variable in a C++ catch
- /// or an Objective-C @catch statement.
- bool ExceptionVar : 1;
+ class VarDeclBitfields {
+ friend class VarDecl;
+ friend class ASTDeclReader;
+
+ unsigned SClass : 3;
+ unsigned SClassAsWritten : 3;
+ unsigned ThreadSpecified : 1;
+ unsigned HasCXXDirectInit : 1;
+
+ /// \brief Whether this variable is the exception variable in a C++ catch
+ /// or an Objective-C @catch statement.
+ unsigned ExceptionVar : 1;
- /// \brief Whether this local variable could be allocated in the return
- /// slot of its function, enabling the named return value optimization (NRVO).
- bool NRVOVariable : 1;
+ /// \brief Whether this local variable could be allocated in the return
+ /// slot of its function, enabling the named return value optimization (NRVO).
+ unsigned NRVOVariable : 1;
+
+ /// \brief Whether this variable is the for-range-declaration in a C++0x
+ /// for-range statement.
+ unsigned CXXForRangeDecl : 1;
+ };
+ enum { NumVarDeclBits = 13 }; // two reserved bits for now
- friend class StmtIteratorBase;
friend class ASTDeclReader;
+ friend class StmtIteratorBase;
protected:
- VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+ class ParmVarDeclBitfields {
+ friend class ParmVarDecl;
+ friend class ASTDeclReader;
+
+ unsigned : NumVarDeclBits;
+
+ /// Whether this parameter inherits a default argument from a
+ /// prior declaration.
+ unsigned HasInheritedDefaultArg : 1;
+
+ /// Whether this parameter undergoes K&R argument promotion.
+ unsigned IsKNRPromoted : 1;
+
+ /// Whether this parameter is an ObjC method parameter or not.
+ unsigned IsObjCMethodParam : 1;
+
+ /// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
+ /// Otherwise, the number of function parameter scopes enclosing
+ /// the function parameter scope in which this parameter was
+ /// declared.
+ unsigned ScopeDepthOrObjCQuals : 8;
+
+ /// The number of parameters preceding this parameter in the
+ /// function parameter scope in which it was declared.
+ unsigned ParameterIndex : 8;
+ };
+
+ union {
+ unsigned AllBits;
+ VarDeclBitfields VarDeclBits;
+ ParmVarDeclBitfields ParmVarDeclBits;
+ };
+
+ VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, StorageClass SC,
StorageClass SCAsWritten)
- : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
- ThreadSpecified(false), HasCXXDirectInit(false),
- ExceptionVar(false), NRVOVariable(false) {
- SClass = SC;
- SClassAsWritten = SCAsWritten;
+ : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() {
+ assert(sizeof(VarDeclBitfields) <= sizeof(unsigned));
+ assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned));
+ AllBits = 0;
+ VarDeclBits.SClass = SC;
+ VarDeclBits.SClassAsWritten = SCAsWritten;
+ // Everything else is implicitly initialized to false.
}
typedef Redeclarable<VarDecl> redeclarable_base;
@@ -691,26 +768,27 @@ public:
}
static VarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, StorageClass S,
- StorageClass SCAsWritten);
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+ StorageClass S, StorageClass SCAsWritten);
- virtual SourceLocation getInnerLocStart() const;
virtual SourceRange getSourceRange() const;
- StorageClass getStorageClass() const { return (StorageClass)SClass; }
+ StorageClass getStorageClass() const {
+ return (StorageClass) VarDeclBits.SClass;
+ }
StorageClass getStorageClassAsWritten() const {
- return (StorageClass) SClassAsWritten;
+ return (StorageClass) VarDeclBits.SClassAsWritten;
}
void setStorageClass(StorageClass SC);
void setStorageClassAsWritten(StorageClass SC) {
assert(isLegalForVariable(SC));
- SClassAsWritten = SC;
+ VarDeclBits.SClassAsWritten = SC;
}
- void setThreadSpecified(bool T) { ThreadSpecified = T; }
+ void setThreadSpecified(bool T) { VarDeclBits.ThreadSpecified = T; }
bool isThreadSpecified() const {
- return ThreadSpecified;
+ return VarDeclBits.ThreadSpecified;
}
/// hasLocalStorage - Returns true if a variable with function scope
@@ -988,7 +1066,7 @@ public:
Eval->IsICE = IsICE;
}
- void setCXXDirectInitializer(bool T) { HasCXXDirectInit = T; }
+ void setCXXDirectInitializer(bool T) { VarDeclBits.HasCXXDirectInit = T; }
/// hasCXXDirectInitializer - If true, the initializer was a direct
/// initializer, e.g: "int x(1);". The Init expression will be the expression
@@ -997,15 +1075,15 @@ public:
/// by checking hasCXXDirectInitializer.
///
bool hasCXXDirectInitializer() const {
- return HasCXXDirectInit;
+ return VarDeclBits.HasCXXDirectInit;
}
/// \brief Determine whether this variable is the exception variable in a
/// C++ catch statememt or an Objective-C @catch statement.
bool isExceptionVariable() const {
- return ExceptionVar;
+ return VarDeclBits.ExceptionVar;
}
- void setExceptionVariable(bool EV) { ExceptionVar = EV; }
+ void setExceptionVariable(bool EV) { VarDeclBits.ExceptionVar = EV; }
/// \brief Determine whether this local variable can be used with the named
/// return value optimization (NRVO).
@@ -1017,8 +1095,13 @@ public:
/// return slot when returning from the function. Within the function body,
/// each return that returns the NRVO object will have this variable as its
/// NRVO candidate.
- bool isNRVOVariable() const { return NRVOVariable; }
- void setNRVOVariable(bool NRVO) { NRVOVariable = NRVO; }
+ bool isNRVOVariable() const { return VarDeclBits.NRVOVariable; }
+ void setNRVOVariable(bool NRVO) { VarDeclBits.NRVOVariable = NRVO; }
+
+ /// \brief Determine whether this variable is the for-range-declaration in
+ /// a C++0x for-range statement.
+ bool isCXXForRangeDecl() const { return VarDeclBits.CXXForRangeDecl; }
+ void setCXXForRangeDecl(bool FRD) { VarDeclBits.CXXForRangeDecl = FRD; }
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
@@ -1048,12 +1131,12 @@ public:
class ImplicitParamDecl : public VarDecl {
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
+ SourceLocation IdLoc, IdentifierInfo *Id,
QualType T);
- ImplicitParamDecl(DeclContext *DC, SourceLocation loc,
- IdentifierInfo *name, QualType type)
- : VarDecl(ImplicitParam, DC, loc, name, type,
+ ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc,
+ IdentifierInfo *Id, QualType Type)
+ : VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type,
/*tinfo*/ 0, SC_None, SC_None) {
setImplicit();
}
@@ -1064,35 +1147,85 @@ public:
static bool classofKind(Kind K) { return K == ImplicitParam; }
};
-/// ParmVarDecl - Represent a parameter to a function.
+/// ParmVarDecl - Represents a parameter to a function.
class ParmVarDecl : public VarDecl {
- // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
- /// FIXME: Also can be paced into the bitfields in Decl.
- /// in, inout, etc.
- unsigned objcDeclQualifier : 6;
- bool HasInheritedDefaultArg : 1;
+public:
+ enum { MaxFunctionScopeDepth = 255 };
+ enum { MaxFunctionScopeIndex = 255 };
protected:
- ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+ ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ QualType T, TypeSourceInfo *TInfo,
StorageClass S, StorageClass SCAsWritten, Expr *DefArg)
- : VarDecl(DK, DC, L, Id, T, TInfo, S, SCAsWritten),
- objcDeclQualifier(OBJC_TQ_None), HasInheritedDefaultArg(false) {
+ : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S, SCAsWritten) {
+ assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
+ assert(ParmVarDeclBits.IsKNRPromoted == false);
+ assert(ParmVarDeclBits.IsObjCMethodParam == false);
setDefaultArg(DefArg);
}
public:
static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,IdentifierInfo *Id,
+ SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, StorageClass SCAsWritten,
Expr *DefArg);
+ void setObjCMethodScopeInfo(unsigned parameterIndex) {
+ ParmVarDeclBits.IsObjCMethodParam = true;
+
+ ParmVarDeclBits.ParameterIndex = parameterIndex;
+ assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!");
+ }
+
+ void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex) {
+ assert(!ParmVarDeclBits.IsObjCMethodParam);
+
+ ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth;
+ assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth && "truncation!");
+
+ ParmVarDeclBits.ParameterIndex = parameterIndex;
+ assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!");
+ }
+
+ bool isObjCMethodParameter() const {
+ return ParmVarDeclBits.IsObjCMethodParam;
+ }
+
+ unsigned getFunctionScopeDepth() const {
+ if (ParmVarDeclBits.IsObjCMethodParam) return 0;
+ return ParmVarDeclBits.ScopeDepthOrObjCQuals;
+ }
+
+ /// Returns the index of this parameter in its prototype or method scope.
+ unsigned getFunctionScopeIndex() const {
+ return ParmVarDeclBits.ParameterIndex;
+ }
+
ObjCDeclQualifier getObjCDeclQualifier() const {
- return ObjCDeclQualifier(objcDeclQualifier);
+ if (!ParmVarDeclBits.IsObjCMethodParam) return OBJC_TQ_None;
+ return ObjCDeclQualifier(ParmVarDeclBits.ScopeDepthOrObjCQuals);
}
void setObjCDeclQualifier(ObjCDeclQualifier QTVal) {
- objcDeclQualifier = QTVal;
+ assert(ParmVarDeclBits.IsObjCMethodParam);
+ ParmVarDeclBits.ScopeDepthOrObjCQuals = QTVal;
+ }
+
+ /// True if the value passed to this parameter must undergo
+ /// K&R-style default argument promotion:
+ ///
+ /// C99 6.5.2.2.
+ /// If the expression that denotes the called function has a type
+ /// that does not include a prototype, the integer promotions are
+ /// performed on each argument, and arguments that have type float
+ /// are promoted to double.
+ bool isKNRPromoted() const {
+ return ParmVarDeclBits.IsKNRPromoted;
+ }
+ void setKNRPromoted(bool promoted) {
+ ParmVarDeclBits.IsKNRPromoted = promoted;
}
Expr *getDefaultArg();
@@ -1158,11 +1291,11 @@ public:
}
bool hasInheritedDefaultArg() const {
- return HasInheritedDefaultArg;
+ return ParmVarDeclBits.HasInheritedDefaultArg;
}
void setHasInheritedDefaultArg(bool I = true) {
- HasInheritedDefaultArg = I;
+ ParmVarDeclBits.HasInheritedDefaultArg = I;
}
QualType getOriginalType() const {
@@ -1233,6 +1366,7 @@ private:
bool IsDeleted : 1;
bool IsTrivial : 1; // sunk from CXXMethodDecl
bool HasImplicitReturnZero : 1;
+ bool IsLateTemplateParsed : 1;
/// \brief End part of this FunctionDecl's source range.
///
@@ -1302,17 +1436,20 @@ private:
void setParams(ASTContext &C, ParmVarDecl **NewParamInfo, unsigned NumParams);
protected:
- FunctionDecl(Kind DK, DeclContext *DC, const DeclarationNameInfo &NameInfo,
+ FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified)
- : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo),
+ : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
+ StartLoc),
DeclContext(DK),
ParamInfo(0), Body(),
- SClass(S), SClassAsWritten(SCAsWritten),
+ SClass(S), SClassAsWritten(SCAsWritten),
IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
- HasImplicitReturnZero(false), EndRangeLoc(NameInfo.getEndLoc()),
+ HasImplicitReturnZero(false), IsLateTemplateParsed(false),
+ EndRangeLoc(NameInfo.getEndLoc()),
TemplateOrSpecialization(),
DNLoc(NameInfo.getInfo()) {}
@@ -1328,22 +1465,25 @@ public:
return redeclarable_base::redecls_end();
}
- static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation NLoc,
DeclarationName N, QualType T,
TypeSourceInfo *TInfo,
- StorageClass S = SC_None,
+ StorageClass SC = SC_None,
StorageClass SCAsWritten = SC_None,
bool isInlineSpecified = false,
bool hasWrittenPrototype = true) {
- DeclarationNameInfo NameInfo(N, L);
- return FunctionDecl::Create(C, DC, NameInfo, T, TInfo, S, SCAsWritten,
+ DeclarationNameInfo NameInfo(N, NLoc);
+ return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo,
+ SC, SCAsWritten,
isInlineSpecified, hasWrittenPrototype);
}
static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
- StorageClass S = SC_None,
+ StorageClass SC = SC_None,
StorageClass SCAsWritten = SC_None,
bool isInlineSpecified = false,
bool hasWrittenPrototype = true);
@@ -1356,12 +1496,9 @@ public:
const PrintingPolicy &Policy,
bool Qualified) const;
- virtual SourceRange getSourceRange() const {
- return SourceRange(getOuterLocStart(), EndRangeLoc);
- }
- void setLocEnd(SourceLocation E) {
- EndRangeLoc = E;
- }
+ void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
+
+ virtual SourceRange getSourceRange() const;
/// \brief Returns true if the function has a body (definition). The
/// function body might be in any of the (re-)declarations of this
@@ -1395,7 +1532,9 @@ public:
/// previous definition); for that information, use getBody.
/// FIXME: Should return true if function is deleted or defaulted. However,
/// CodeGenModule.cpp uses it, and I don't know if this would break it.
- bool isThisDeclarationADefinition() const { return Body; }
+ bool isThisDeclarationADefinition() const {
+ return Body || IsLateTemplateParsed;
+ }
void setBody(Stmt *B);
void setLazyBody(uint64_t Offset) { Body = Offset; }
@@ -1412,6 +1551,14 @@ public:
bool isPure() const { return IsPure; }
void setPure(bool P = true);
+ /// Whether this is a constexpr function or constexpr constructor.
+ // FIXME: C++0x: Implement tracking of the constexpr specifier.
+ bool isConstExpr() const { return false; }
+
+ /// Whether this templated function will be late parsed.
+ bool isLateTemplateParsed() const { return IsLateTemplateParsed; }
+ void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; }
+
/// Whether this function is "trivial" in some specialized C++ senses.
/// Can only be true for default constructors, copy constructors,
/// copy assignment operators, and destructors. Not meaningful until
@@ -1757,16 +1904,17 @@ class FieldDecl : public DeclaratorDecl {
Expr *BitWidth;
protected:
- FieldDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
- Expr *BW, bool Mutable)
- : DeclaratorDecl(DK, DC, L, Id, T, TInfo),
+ FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable)
+ : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
Mutable(Mutable), CachedFieldIndex(0), BitWidth(BW) {
}
public:
static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id, QualType T,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable);
/// getFieldIndex - Returns the index of this field within its record,
@@ -1803,7 +1951,9 @@ public:
RecordDecl *getParent() {
return cast<RecordDecl>(getDeclContext());
}
-
+
+ SourceRange getSourceRange() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FieldDecl *D) { return true; }
@@ -1895,6 +2045,8 @@ class TypeDecl : public NamedDecl {
/// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
/// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl.
mutable const Type *TypeForDecl;
+ /// LocStart - The start of the source range for this declaration.
+ SourceLocation LocStart;
friend class ASTContext;
friend class DeclContext;
friend class TagDecl;
@@ -1902,15 +2054,24 @@ class TypeDecl : public NamedDecl {
friend class TagType;
protected:
- TypeDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id)
- : NamedDecl(DK, DC, L, Id), TypeForDecl(0) {}
+ TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+ SourceLocation StartL = SourceLocation())
+ : NamedDecl(DK, DC, L, Id), TypeForDecl(0), LocStart(StartL) {}
public:
// Low-level accessor
const Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(const Type *TD) { TypeForDecl = TD; }
+ SourceLocation getLocStart() const { return LocStart; }
+ void setLocStart(SourceLocation L) { LocStart = L; }
+ virtual SourceRange getSourceRange() const {
+ if (LocStart.isValid())
+ return SourceRange(LocStart, getLocation());
+ else
+ return SourceRange(getLocation());
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypeDecl *D) { return true; }
@@ -1918,17 +2079,21 @@ public:
};
-class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
+/// Base class for declarations which introduce a typedef-name.
+class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
/// UnderlyingType - This is the type the typedef is set to.
TypeSourceInfo *TInfo;
- TypedefDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
-
protected:
- typedef Redeclarable<TypedefDecl> redeclarable_base;
- virtual TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+ TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ TypeSourceInfo *TInfo)
+ : TypeDecl(DK, DC, IdLoc, Id, StartLoc), TInfo(TInfo) {}
+
+ typedef Redeclarable<TypedefNameDecl> redeclarable_base;
+ virtual TypedefNameDecl *getNextRedeclaration() {
+ return RedeclLink.getNext();
+ }
public:
typedef redeclarable_base::redecl_iterator redecl_iterator;
@@ -1939,19 +2104,15 @@ public:
return redeclarable_base::redecls_end();
}
- static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- TypeSourceInfo *TInfo);
-
TypeSourceInfo *getTypeSourceInfo() const {
return TInfo;
}
- /// Retrieves the canonical declaration of this typedef.
- TypedefDecl *getCanonicalDecl() {
+ /// Retrieves the canonical declaration of this typedef-name.
+ TypedefNameDecl *getCanonicalDecl() {
return getFirstDeclaration();
}
- const TypedefDecl *getCanonicalDecl() const {
+ const TypedefNameDecl *getCanonicalDecl() const {
return getFirstDeclaration();
}
@@ -1964,11 +2125,51 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const TypedefNameDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= firstTypedefName && K <= lastTypedefName;
+ }
+};
+
+/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
+/// type specifier.
+class TypedefDecl : public TypedefNameDecl {
+ TypedefDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, TypeSourceInfo *TInfo)
+ : TypedefNameDecl(Typedef, DC, StartLoc, IdLoc, Id, TInfo) {}
+
+public:
+ static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, TypeSourceInfo *TInfo);
+
+ SourceRange getSourceRange() const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypedefDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Typedef; }
};
-class TypedefDecl;
+/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
+/// alias-declaration.
+class TypeAliasDecl : public TypedefNameDecl {
+ TypeAliasDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, TypeSourceInfo *TInfo)
+ : TypedefNameDecl(TypeAlias, DC, StartLoc, IdLoc, Id, TInfo) {}
+
+public:
+ static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, TypeSourceInfo *TInfo);
+
+ SourceRange getSourceRange() const;
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const TypeAliasDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == TypeAlias; }
+};
/// TagDecl - Represents the declaration of a struct/union/class/enum.
class TagDecl
@@ -2013,32 +2214,31 @@ protected:
bool IsFixed : 1;
private:
- SourceLocation TagKeywordLoc;
SourceLocation RBraceLoc;
// A struct representing syntactic qualifier info,
// to be used for the (uncommon) case of out-of-line declarations.
typedef QualifierInfo ExtInfo;
- /// TypedefDeclOrQualifier - If the (out-of-line) tag declaration name
+ /// TypedefNameDeclOrQualifier - If the (out-of-line) tag declaration name
/// is qualified, it points to the qualifier info (nns and range);
/// otherwise, if the tag declaration is anonymous and it is part of
- /// a typedef, it points to the TypedefDecl (used for mangling);
- /// otherwise, it is a null (TypedefDecl) pointer.
- llvm::PointerUnion<TypedefDecl*, ExtInfo*> TypedefDeclOrQualifier;
+ /// a typedef or alias, it points to the TypedefNameDecl (used for mangling);
+ /// otherwise, it is a null (TypedefNameDecl) pointer.
+ llvm::PointerUnion<TypedefNameDecl*, ExtInfo*> TypedefNameDeclOrQualifier;
- bool hasExtInfo() const { return TypedefDeclOrQualifier.is<ExtInfo*>(); }
- ExtInfo *getExtInfo() { return TypedefDeclOrQualifier.get<ExtInfo*>(); }
+ bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo*>(); }
+ ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo*>(); }
const ExtInfo *getExtInfo() const {
- return TypedefDeclOrQualifier.get<ExtInfo*>();
+ return TypedefNameDeclOrQualifier.get<ExtInfo*>();
}
protected:
TagDecl(Kind DK, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- TagDecl *PrevDecl, SourceLocation TKL = SourceLocation())
- : TypeDecl(DK, DC, L, Id), DeclContext(DK), TagKeywordLoc(TKL),
- TypedefDeclOrQualifier((TypedefDecl*) 0) {
+ TagDecl *PrevDecl, SourceLocation StartL)
+ : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK),
+ TypedefNameDeclOrQualifier((TypedefNameDecl*) 0) {
assert((DK != Enum || TK == TTK_Enum) &&
"EnumDecl not matched with TTK_Enum");
TagDeclKind = TK;
@@ -2068,12 +2268,9 @@ public:
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
- SourceLocation getTagKeywordLoc() const { return TagKeywordLoc; }
- void setTagKeywordLoc(SourceLocation TKL) { TagKeywordLoc = TKL; }
-
/// getInnerLocStart - Return SourceLocation representing start of source
/// range ignoring outer template declarations.
- virtual SourceLocation getInnerLocStart() const { return TagKeywordLoc; }
+ SourceLocation getInnerLocStart() const { return getLocStart(); }
/// getOuterLocStart - Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
@@ -2146,11 +2343,11 @@ public:
bool isUnion() const { return getTagKind() == TTK_Union; }
bool isEnum() const { return getTagKind() == TTK_Enum; }
- TypedefDecl *getTypedefForAnonDecl() const {
- return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
+ TypedefNameDecl *getTypedefNameForAnonDecl() const {
+ return hasExtInfo() ? 0 : TypedefNameDeclOrQualifier.get<TypedefNameDecl*>();
}
- void setTypedefForAnonDecl(TypedefDecl *TDD);
+ void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
/// \brief Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
@@ -2177,9 +2374,7 @@ public:
return getExtInfo()->TemplParamLists[i];
}
void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
- TemplateParameterList **TPLists) {
- getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
- }
+ TemplateParameterList **TPLists);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2235,18 +2430,19 @@ class EnumDecl : public TagDecl {
NumBitsMask = (1 << NumBitsWidth) - 1
};
- EnumDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL,
+ EnumDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, EnumDecl *PrevDecl,
bool Scoped, bool ScopedUsingClassTag, bool Fixed)
- : TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
- assert(Scoped || !ScopedUsingClassTag);
- IntegerType = (const Type*)0;
- NumNegativeBits = 0;
- NumPositiveBits = 0;
- IsScoped = Scoped;
- IsScopedUsingClassTag = ScopedUsingClassTag;
- IsFixed = Fixed;
- }
+ : TagDecl(Enum, TTK_Enum, DC, IdLoc, Id, PrevDecl, StartLoc),
+ InstantiatedFrom(0) {
+ assert(Scoped || !ScopedUsingClassTag);
+ IntegerType = (const Type*)0;
+ NumNegativeBits = 0;
+ NumPositiveBits = 0;
+ IsScoped = Scoped;
+ IsScopedUsingClassTag = ScopedUsingClassTag;
+ IsFixed = Fixed;
+ }
public:
EnumDecl *getCanonicalDecl() {
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
@@ -2263,8 +2459,8 @@ public:
}
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- SourceLocation TKL, EnumDecl *PrevDecl,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, EnumDecl *PrevDecl,
bool IsScoped, bool IsScopedUsingClassTag,
bool IsFixed);
static EnumDecl *Create(ASTContext &C, EmptyShell Empty);
@@ -2326,7 +2522,7 @@ public:
return IntegerType.dyn_cast<TypeSourceInfo*>();
}
- /// \brief Returns the width in bits requred to store all the
+ /// \brief Returns the width in bits required to store all the
/// non-negative enumerators of this enum.
unsigned getNumPositiveBits() const {
return NumPositiveBits;
@@ -2336,7 +2532,7 @@ public:
assert(NumPositiveBits == Num && "can't store this bitcount");
}
- /// \brief Returns the width in bits requred to store all the
+ /// \brief Returns the width in bits required to store all the
/// negative enumerators of this enum. These widths include
/// the rightmost leading 1; that is:
///
@@ -2419,14 +2615,13 @@ class RecordDecl : public TagDecl {
protected:
RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- RecordDecl *PrevDecl, SourceLocation TKL);
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, RecordDecl *PrevDecl);
public:
static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- SourceLocation TKL = SourceLocation(),
- RecordDecl* PrevDecl = 0);
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, RecordDecl* PrevDecl = 0);
static RecordDecl *Create(const ASTContext &C, EmptyShell Empty);
const RecordDecl *getPreviousDeclaration() const {
@@ -2519,11 +2714,21 @@ private:
class FileScopeAsmDecl : public Decl {
StringLiteral *AsmString;
- FileScopeAsmDecl(DeclContext *DC, SourceLocation L, StringLiteral *asmstring)
- : Decl(FileScopeAsm, DC, L), AsmString(asmstring) {}
+ SourceLocation RParenLoc;
+ FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring,
+ SourceLocation StartL, SourceLocation EndL)
+ : Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {}
public:
static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, StringLiteral *Str);
+ StringLiteral *Str, SourceLocation AsmLoc,
+ SourceLocation RParenLoc);
+
+ SourceLocation getAsmLoc() const { return getLocation(); }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+ SourceRange getSourceRange() const {
+ return SourceRange(getAsmLoc(), getRParenLoc());
+ }
const StringLiteral *getAsmString() const { return AsmString; }
StringLiteral *getAsmString() { return AsmString; }
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index b35d134d0534..ce48187f3ade 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -62,6 +62,15 @@ public:
namespace clang {
+ /// \brief Captures the result of checking the availability of a
+ /// declaration.
+ enum AvailabilityResult {
+ AR_Available = 0,
+ AR_NotYetIntroduced,
+ AR_Deprecated,
+ AR_Unavailable
+ };
+
/// Decl - This represents one declaration (or definition), e.g. a variable,
/// typedef, function, struct, etc.
///
@@ -147,9 +156,20 @@ public:
IDNS_NonMemberOperator = 0x0400
};
- /// ObjCDeclQualifier - Qualifier used on types in method declarations
- /// for remote messaging. They are meant for the arguments though and
- /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
+ /// ObjCDeclQualifier - 'Qualifiers' written next to the return and
+ /// parameter types in method declarations. Other than remembering
+ /// them and mangling them into the method's signature string, these
+ /// are ignored by the compiler; they are consumed by certain
+ /// remote-messaging frameworks.
+ ///
+ /// in, inout, and out are mutually exclusive and apply only to
+ /// method parameters. bycopy and byref are mutually exclusive and
+ /// apply only to method parameters (?). oneway applies only to
+ /// results. All of these expect their corresponding parameter to
+ /// have a particular type. None of this is currently enforced by
+ /// clang.
+ ///
+ /// This should be kept in sync with ObjCDeclSpec::ObjCDeclQualifier.
enum ObjCDeclQualifier {
OBJC_TQ_None = 0x0,
OBJC_TQ_In = 0x1,
@@ -218,6 +238,12 @@ private:
/// required.
unsigned Used : 1;
+ /// \brief Whether this declaration was "referenced".
+ /// The difference with 'Used' is whether the reference appears in a
+ /// evaluated context or not, e.g. functions used in uninstantiated templates
+ /// are regarded as "referenced" but not "used".
+ unsigned Referenced : 1;
+
protected:
/// Access - Used by C++ decls for the access specifier.
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
@@ -252,7 +278,7 @@ protected:
Decl(Kind DK, DeclContext *DC, SourceLocation L)
: NextDeclInContext(0), DeclCtx(DC),
Loc(L), DeclKind(DK), InvalidDecl(0),
- HasAttrs(false), Implicit(false), Used(false),
+ HasAttrs(false), Implicit(false), Used(false), Referenced(false),
Access(AS_none), PCHLevel(0), ChangedAfterLoad(false),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
HasCachedLinkage(0)
@@ -262,7 +288,7 @@ protected:
Decl(Kind DK, EmptyShell Empty)
: NextDeclInContext(0), DeclKind(DK), InvalidDecl(0),
- HasAttrs(false), Implicit(false), Used(false),
+ HasAttrs(false), Implicit(false), Used(false), Referenced(false),
Access(AS_none), PCHLevel(0), ChangedAfterLoad(false),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
HasCachedLinkage(0)
@@ -399,6 +425,57 @@ public:
void setUsed(bool U = true) { Used = U; }
+ /// \brief Whether this declaration was referenced.
+ bool isReferenced() const;
+
+ void setReferenced(bool R = true) { Referenced = R; }
+
+ /// \brief Determine the availability of the given declaration.
+ ///
+ /// This routine will determine the most restrictive availability of
+ /// the given declaration (e.g., preferring 'unavailable' to
+ /// 'deprecated').
+ ///
+ /// \param Message If non-NULL and the result is not \c
+ /// AR_Available, will be set to a (possibly empty) message
+ /// describing why the declaration has not been introduced, is
+ /// deprecated, or is unavailable.
+ AvailabilityResult getAvailability(std::string *Message = 0) const;
+
+ /// \brief Determine whether this declaration is marked 'deprecated'.
+ ///
+ /// \param Message If non-NULL and the declaration is deprecated,
+ /// this will be set to the message describing why the declaration
+ /// was deprecated (which may be empty).
+ bool isDeprecated(std::string *Message = 0) const {
+ return getAvailability(Message) == AR_Deprecated;
+ }
+
+ /// \brief Determine whether this declaration is marked 'unavailable'.
+ ///
+ /// \param Message If non-NULL and the declaration is unavailable,
+ /// this will be set to the message describing why the declaration
+ /// was made unavailable (which may be empty).
+ bool isUnavailable(std::string *Message = 0) const {
+ return getAvailability(Message) == AR_Unavailable;
+ }
+
+ /// \brief Determine whether this is a weak-imported symbol.
+ ///
+ /// Weak-imported symbols are typically marked with the
+ /// 'weak_import' attribute, but may also be marked with an
+ /// 'availability' attribute where we're targing a platform prior to
+ /// the introduction of this feature.
+ bool isWeakImported() const;
+
+ /// \brief Determines whether this symbol can be weak-imported,
+ /// e.g., whether it would be well-formed to add the weak_import
+ /// attribute.
+ ///
+ /// \param IsDefinition Set to \c true to indicate that this
+ /// declaration cannot be weak-imported because it has a definition.
+ bool canBeWeakImported(bool &IsDefinition) const;
+
/// \brief Retrieve the level of precompiled header from which this
/// declaration was generated.
///
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 1656a7e9737c..8c819e38781d 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -306,6 +306,37 @@ class CXXRecordDecl : public RecordDecl {
/// one pure virtual function, (that can come from a base class).
bool Abstract : 1;
+ /// IsStandardLayout - True when this class has standard layout.
+ ///
+ /// C++0x [class]p7. A standard-layout class is a class that:
+ /// * has no non-static data members of type non-standard-layout class (or
+ /// array of such types) or reference,
+ /// * has no virtual functions (10.3) and no virtual base classes (10.1),
+ /// * has the same access control (Clause 11) for all non-static data members
+ /// * has no non-standard-layout base classes,
+ /// * either has no non-static data members in the most derived class and at
+ /// most one base class with non-static data members, or has no base
+ /// classes with non-static data members, and
+ /// * has no base classes of the same type as the first non-static data
+ /// member.
+ bool IsStandardLayout : 1;
+
+ /// HasNoNonEmptyBases - True when there are no non-empty base classes.
+ ///
+ /// This is a helper bit of state used to implement IsStandardLayout more
+ /// efficiently.
+ bool HasNoNonEmptyBases : 1;
+
+ /// HasPrivateFields - True when there are private non-static data members.
+ bool HasPrivateFields : 1;
+
+ /// HasProtectedFields - True when there are protected non-static data
+ /// members.
+ bool HasProtectedFields : 1;
+
+ /// HasPublicFields - True when there are private non-static data members.
+ bool HasPublicFields : 1;
+
/// HasTrivialConstructor - True when this class has a trivial constructor.
///
/// C++ [class.ctor]p5. A constructor is trivial if it is an
@@ -316,31 +347,71 @@ class CXXRecordDecl : public RecordDecl {
/// (or array thereof), each such class has a trivial constructor.
bool HasTrivialConstructor : 1;
+ /// HasConstExprNonCopyMoveConstructor - True when this class has at least
+ /// one constexpr constructor which is neither the copy nor move
+ /// constructor.
+ bool HasConstExprNonCopyMoveConstructor : 1;
+
/// HasTrivialCopyConstructor - True when this class has a trivial copy
/// constructor.
///
- /// C++ [class.copy]p6. A copy constructor for class X is trivial
- /// if it is implicitly declared and if
- /// * class X has no virtual functions and no virtual base classes, and
- /// * each direct base class of X has a trivial copy constructor, and
- /// * for all the nonstatic data members of X that are of class type (or
- /// array thereof), each such class type has a trivial copy constructor;
- /// otherwise the copy constructor is non-trivial.
+ /// C++0x [class.copy]p13:
+ /// A copy/move constructor for class X is trivial if it is neither
+ /// user-provided nor deleted and if
+ /// -- class X has no virtual functions and no virtual base classes, and
+ /// -- the constructor selected to copy/move each direct base class
+ /// subobject is trivial, and
+ /// -- for each non-static data member of X that is of class type (or an
+ /// array thereof), the constructor selected to copy/move that member
+ /// is trivial;
+ /// otherwise the copy/move constructor is non-trivial.
bool HasTrivialCopyConstructor : 1;
+ /// HasTrivialMoveConstructor - True when this class has a trivial move
+ /// constructor.
+ ///
+ /// C++0x [class.copy]p13:
+ /// A copy/move constructor for class X is trivial if it is neither
+ /// user-provided nor deleted and if
+ /// -- class X has no virtual functions and no virtual base classes, and
+ /// -- the constructor selected to copy/move each direct base class
+ /// subobject is trivial, and
+ /// -- for each non-static data member of X that is of class type (or an
+ /// array thereof), the constructor selected to copy/move that member
+ /// is trivial;
+ /// otherwise the copy/move constructor is non-trivial.
+ bool HasTrivialMoveConstructor : 1;
+
/// HasTrivialCopyAssignment - True when this class has a trivial copy
/// assignment operator.
///
- /// C++ [class.copy]p11. A copy assignment operator for class X is
- /// trivial if it is implicitly declared and if
- /// * class X has no virtual functions and no virtual base classes, and
- /// * each direct base class of X has a trivial copy assignment operator, and
- /// * for all the nonstatic data members of X that are of class type (or
- /// array thereof), each such class type has a trivial copy assignment
- /// operator;
- /// otherwise the copy assignment operator is non-trivial.
+ /// C++0x [class.copy]p27:
+ /// A copy/move assignment operator for class X is trivial if it is
+ /// neither user-provided nor deleted and if
+ /// -- class X has no virtual functions and no virtual base classes, and
+ /// -- the assignment operator selected to copy/move each direct base
+ /// class subobject is trivial, and
+ /// -- for each non-static data member of X that is of class type (or an
+ /// array thereof), the assignment operator selected to copy/move
+ /// that member is trivial;
+ /// otherwise the copy/move assignment operator is non-trivial.
bool HasTrivialCopyAssignment : 1;
+ /// HasTrivialMoveAssignment - True when this class has a trivial move
+ /// assignment operator.
+ ///
+ /// C++0x [class.copy]p27:
+ /// A copy/move assignment operator for class X is trivial if it is
+ /// neither user-provided nor deleted and if
+ /// -- class X has no virtual functions and no virtual base classes, and
+ /// -- the assignment operator selected to copy/move each direct base
+ /// class subobject is trivial, and
+ /// -- for each non-static data member of X that is of class type (or an
+ /// array thereof), the assignment operator selected to copy/move
+ /// that member is trivial;
+ /// otherwise the copy/move assignment operator is non-trivial.
+ bool HasTrivialMoveAssignment : 1;
+
/// HasTrivialDestructor - True when this class has a trivial destructor.
///
/// C++ [class.dtor]p3. A destructor is trivial if it is an
@@ -351,6 +422,10 @@ class CXXRecordDecl : public RecordDecl {
/// type (or array thereof), each such class has a trivial destructor.
bool HasTrivialDestructor : 1;
+ /// HasNonLiteralTypeFieldsOrBases - True when this class contains at least
+ /// one non-static data member or base class of non literal type.
+ bool HasNonLiteralTypeFieldsOrBases : 1;
+
/// ComputedVisibleConversions - True when visible conversion functions are
/// already computed and are available.
bool ComputedVisibleConversions : 1;
@@ -449,9 +524,8 @@ class CXXRecordDecl : public RecordDecl {
protected:
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- CXXRecordDecl *PrevDecl,
- SourceLocation TKL = SourceLocation());
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
public:
/// base_class_iterator - Iterator that traverses the base classes
@@ -494,9 +568,8 @@ public:
bool hasDefinition() const { return DefinitionData != 0; }
static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- SourceLocation TKL = SourceLocation(),
- CXXRecordDecl* PrevDecl=0,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0,
bool DelayTypeCreation = false);
static CXXRecordDecl *Create(const ASTContext &C, EmptyShell Empty);
@@ -723,26 +796,58 @@ public:
/// which means that the class contains or inherits a pure virtual function.
bool isAbstract() const { return data().Abstract; }
+ /// isStandardLayout - Whether this class has standard layout
+ /// (C++ [class]p7)
+ bool isStandardLayout() const { return data().IsStandardLayout; }
+
// hasTrivialConstructor - Whether this class has a trivial constructor
// (C++ [class.ctor]p5)
bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
+ // hasConstExprNonCopyMoveConstructor - Whether this class has at least one
+ // constexpr constructor other than the copy or move constructors
+ bool hasConstExprNonCopyMoveConstructor() const {
+ return data().HasConstExprNonCopyMoveConstructor;
+ }
+
// hasTrivialCopyConstructor - Whether this class has a trivial copy
- // constructor (C++ [class.copy]p6)
+ // constructor (C++ [class.copy]p6, C++0x [class.copy]p13)
bool hasTrivialCopyConstructor() const {
return data().HasTrivialCopyConstructor;
}
+ // hasTrivialMoveConstructor - Whether this class has a trivial move
+ // constructor (C++0x [class.copy]p13)
+ bool hasTrivialMoveConstructor() const {
+ return data().HasTrivialMoveConstructor;
+ }
+
// hasTrivialCopyAssignment - Whether this class has a trivial copy
- // assignment operator (C++ [class.copy]p11)
+ // assignment operator (C++ [class.copy]p11, C++0x [class.copy]p27)
bool hasTrivialCopyAssignment() const {
return data().HasTrivialCopyAssignment;
}
+ // hasTrivialMoveAssignment - Whether this class has a trivial move
+ // assignment operator (C++0x [class.copy]p27)
+ bool hasTrivialMoveAssignment() const {
+ return data().HasTrivialMoveAssignment;
+ }
+
// hasTrivialDestructor - Whether this class has a trivial destructor
// (C++ [class.dtor]p3)
bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
+ // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal type
+ // non-static data member or base class.
+ bool hasNonLiteralTypeFieldsOrBases() const {
+ return data().HasNonLiteralTypeFieldsOrBases;
+ }
+
+ // isTriviallyCopyable - Whether this class is considered trivially copyable
+ // (C++0x [class]p5).
+ bool isTriviallyCopyable() const;
+
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
@@ -1034,20 +1139,27 @@ public:
/// struct/union/class.
class CXXMethodDecl : public FunctionDecl {
protected:
- CXXMethodDecl(Kind DK, CXXRecordDecl *RD,
+ CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
- bool isStatic, StorageClass SCAsWritten, bool isInline)
- : FunctionDecl(DK, RD, NameInfo, T, TInfo, (isStatic ? SC_Static : SC_None),
- SCAsWritten, isInline) {}
+ bool isStatic, StorageClass SCAsWritten, bool isInline,
+ SourceLocation EndLocation)
+ : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo,
+ (isStatic ? SC_Static : SC_None),
+ SCAsWritten, isInline) {
+ if (EndLocation.isValid())
+ setRangeEnd(EndLocation);
+ }
public:
static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
- bool isStatic = false,
- StorageClass SCAsWritten = SC_None,
- bool isInline = false);
+ bool isStatic,
+ StorageClass SCAsWritten,
+ bool isInline,
+ SourceLocation EndLocation);
bool isStatic() const { return getStorageClass() == SC_Static; }
bool isInstance() const { return !isStatic(); }
@@ -1148,13 +1260,16 @@ public:
/// @endcode
class CXXCtorInitializer {
/// \brief Either the base class name (stored as a TypeSourceInfo*), an normal
- /// field (FieldDecl) or an anonymous field (IndirectFieldDecl*) being
- /// initialized.
- llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *>
+ /// field (FieldDecl), anonymous field (IndirectFieldDecl*), or target
+ /// constructor (CXXConstructorDecl*) being initialized.
+ llvm::PointerUnion4<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *,
+ CXXConstructorDecl *>
Initializee;
/// \brief The source location for the field name or, for a base initializer
- /// pack expansion, the location of the ellipsis.
+ /// pack expansion, the location of the ellipsis. In the case of a delegating
+ /// constructor, it will still include the type's source location as the
+ /// Initializee points to the CXXConstructorDecl (to allow loop detection).
SourceLocation MemberOrEllipsisLocation;
/// \brief The argument used to initialize the base or member, which may
@@ -1199,11 +1314,17 @@ public:
SourceLocation MemberLoc, SourceLocation L, Expr *Init,
SourceLocation R);
+ /// CXXCtorInitializer - Creates a new anonymous field initializer.
explicit
CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,
SourceLocation MemberLoc, SourceLocation L, Expr *Init,
SourceLocation R);
+ /// CXXCtorInitializer - Creates a new delegating Initializer.
+ explicit
+ CXXCtorInitializer(ASTContext &Context, SourceLocation D, SourceLocation L,
+ CXXConstructorDecl *Target, Expr *Init, SourceLocation R);
+
/// \brief Creates a new member initializer that optionally contains
/// array indices used to describe an elementwise initialization.
static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
@@ -1227,6 +1348,12 @@ public:
return Initializee.is<IndirectFieldDecl*>();
}
+ /// isDelegatingInitializer - Returns true when this initializer is creating
+ /// a delegating constructor.
+ bool isDelegatingInitializer() const {
+ return Initializee.is<CXXConstructorDecl *>();
+ }
+
/// \brief Determine whether this initializer is a pack expansion.
bool isPackExpansion() const {
return isBaseInitializer() && MemberOrEllipsisLocation.isValid();
@@ -1284,6 +1411,13 @@ public:
return 0;
}
+ CXXConstructorDecl *getTargetConstructor() const {
+ if (isDelegatingInitializer())
+ return Initializee.get<CXXConstructorDecl*>();
+ else
+ return 0;
+ }
+
SourceLocation getMemberLocation() const {
return MemberOrEllipsisLocation;
}
@@ -1373,12 +1507,13 @@ class CXXConstructorDecl : public CXXMethodDecl {
CXXCtorInitializer **CtorInitializers;
unsigned NumCtorInitializers;
- CXXConstructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
+ CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXConstructor, RD, NameInfo, T, TInfo, false,
- SC_None, isInline),
+ : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, false,
+ SC_None, isInline, SourceLocation()),
IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
CtorInitializers(0), NumCtorInitializers(0) {
setImplicit(isImplicitlyDeclared);
@@ -1387,6 +1522,7 @@ class CXXConstructorDecl : public CXXMethodDecl {
public:
static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isExplicit,
@@ -1472,6 +1608,23 @@ public:
void setCtorInitializers(CXXCtorInitializer ** initializers) {
CtorInitializers = initializers;
}
+
+ /// isDelegatingConstructor - Whether this constructor is a
+ /// delegating constructor
+ bool isDelegatingConstructor() const {
+ return (getNumCtorInitializers() == 1) &&
+ CtorInitializers[0]->isDelegatingInitializer();
+ }
+
+ /// getTargetConstructor - When this constructor delegates to
+ /// another, retrieve the target
+ CXXConstructorDecl *getTargetConstructor() const {
+ if (isDelegatingConstructor())
+ return CtorInitializers[0]->getTargetConstructor();
+ else
+ return 0;
+ }
+
/// isDefaultConstructor - Whether this constructor is a default
/// constructor (C++ [class.ctor]p5), which can be used to
/// default-initialize a class of this type.
@@ -1508,8 +1661,11 @@ public:
/// \brief Determine whether this constructor is a move constructor
/// (C++0x [class.copy]p3), which can be used to move values of the class.
- bool isMoveConstructor() const;
-
+ bool isMoveConstructor() const {
+ unsigned TypeQuals = 0;
+ return isMoveConstructor(TypeQuals);
+ }
+
/// \brief Determine whether this is a copy or move constructor.
///
/// \param TypeQuals Will be set to the type qualifiers on the reference
@@ -1567,11 +1723,12 @@ class CXXDestructorDecl : public CXXMethodDecl {
FunctionDecl *OperatorDelete;
- CXXDestructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
+ CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, NameInfo, T, TInfo, false,
- SC_None, isInline),
+ : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, false,
+ SC_None, isInline, SourceLocation()),
ImplicitlyDefined(false), OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -1579,6 +1736,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
public:
static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo* TInfo,
bool isInline,
@@ -1629,19 +1787,23 @@ class CXXConversionDecl : public CXXMethodDecl {
/// explicitly wrote a cast. This is a C++0x feature.
bool IsExplicitSpecified : 1;
- CXXConversionDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
+ CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isExplicitSpecified)
- : CXXMethodDecl(CXXConversion, RD, NameInfo, T, TInfo, false,
- SC_None, isInline),
+ bool isInline, bool isExplicitSpecified,
+ SourceLocation EndLocation)
+ : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, false,
+ SC_None, isInline, EndLocation),
IsExplicitSpecified(isExplicitSpecified) { }
public:
static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isExplicit);
+ bool isInline, bool isExplicit,
+ SourceLocation EndLocation);
/// IsExplicitSpecified - Whether this conversion function declaration is
/// marked "explicit", meaning that it can only be applied when the user
@@ -1688,33 +1850,48 @@ public:
private:
/// Language - The language for this linkage specification.
LanguageIDs Language;
+ /// ExternLoc - The source location for the extern keyword.
+ SourceLocation ExternLoc;
+ /// RBraceLoc - The source location for the right brace (if valid).
+ SourceLocation RBraceLoc;
- /// HadBraces - Whether this linkage specification had curly braces or not.
- bool HadBraces : 1;
-
- LinkageSpecDecl(DeclContext *DC, SourceLocation L, LanguageIDs lang,
- bool Braces)
- : Decl(LinkageSpec, DC, L),
- DeclContext(LinkageSpec), Language(lang), HadBraces(Braces) { }
+ LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
+ SourceLocation LangLoc, LanguageIDs lang,
+ SourceLocation RBLoc)
+ : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
+ Language(lang), ExternLoc(ExternLoc), RBraceLoc(RBLoc) { }
public:
static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, LanguageIDs Lang,
- bool Braces);
+ SourceLocation ExternLoc,
+ SourceLocation LangLoc, LanguageIDs Lang,
+ SourceLocation RBraceLoc = SourceLocation());
/// \brief Return the language specified by this linkage specification.
LanguageIDs getLanguage() const { return Language; }
-
/// \brief Set the language specified by this linkage specification.
void setLanguage(LanguageIDs L) { Language = L; }
/// \brief Determines whether this linkage specification had braces in
/// its syntactic form.
- bool hasBraces() const { return HadBraces; }
+ bool hasBraces() const { return RBraceLoc.isValid(); }
- /// \brief Set whether this linkage specification has braces in its
- /// syntactic form.
- void setHasBraces(bool B) { HadBraces = B; }
+ SourceLocation getExternLoc() const { return ExternLoc; }
+ SourceLocation getRBraceLoc() const { return RBraceLoc; }
+ void setExternLoc(SourceLocation L) { ExternLoc = L; }
+ void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+
+ SourceLocation getLocEnd() const {
+ if (hasBraces())
+ return getRBraceLoc();
+ // No braces: get the end location of the (only) declaration in context
+ // (if present).
+ return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
+ }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(ExternLoc, getLocEnd());
+ }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const LinkageSpecDecl *D) { return true; }
@@ -2023,12 +2200,6 @@ public:
return QualifierLoc.getNestedNameSpecifier();
}
- /// \brief Retrieve the source range of the nested-name-specifier
- /// that qualifies the name.
- SourceRange getQualifierRange() const {
- return QualifierLoc.getSourceRange();
- }
-
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
@@ -2154,12 +2325,6 @@ public:
return QualifierLoc.getNestedNameSpecifier();
}
- /// \brief Retrieve the source range of the nested-name-specifier
- /// that qualifies the name.
- SourceRange getQualifierRange() const {
- return QualifierLoc.getSourceRange();
- }
-
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
@@ -2205,15 +2370,15 @@ class UnresolvedUsingTypenameDecl : public TypeDecl {
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TargetNameLoc,
IdentifierInfo *TargetName)
- : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
- UsingLocation(UsingLoc), TypenameLocation(TypenameLoc),
- QualifierLoc(QualifierLoc) { }
+ : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
+ UsingLoc),
+ TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }
friend class ASTDeclReader;
public:
/// \brief Returns the source location of the 'using' keyword.
- SourceLocation getUsingLoc() const { return UsingLocation; }
+ SourceLocation getUsingLoc() const { return getLocStart(); }
/// \brief Returns the source location of the 'typename' keyword.
SourceLocation getTypenameLoc() const { return TypenameLocation; }
@@ -2227,22 +2392,11 @@ public:
return QualifierLoc.getNestedNameSpecifier();
}
- /// \brief Retrieve the source range of the nested-name-specifier
- /// that qualifies the name.
- SourceRange getQualifierRange() const {
- return QualifierLoc.getSourceRange();
- }
-
- // FIXME: DeclarationNameInfo
static UnresolvedUsingTypenameDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TargetNameLoc, DeclarationName TargetName);
- SourceRange getSourceRange() const {
- return SourceRange(UsingLocation, getLocation());
- }
-
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
@@ -2252,15 +2406,19 @@ public:
class StaticAssertDecl : public Decl {
Expr *AssertExpr;
StringLiteral *Message;
+ SourceLocation RParenLoc;
- StaticAssertDecl(DeclContext *DC, SourceLocation L,
- Expr *assertexpr, StringLiteral *message)
- : Decl(StaticAssert, DC, L), AssertExpr(assertexpr), Message(message) { }
+ StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc,
+ Expr *assertexpr, StringLiteral *message,
+ SourceLocation RParenLoc)
+ : Decl(StaticAssert, DC, StaticAssertLoc), AssertExpr(assertexpr),
+ Message(message), RParenLoc(RParenLoc) { }
public:
static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, Expr *AssertExpr,
- StringLiteral *Message);
+ SourceLocation StaticAssertLoc,
+ Expr *AssertExpr, StringLiteral *Message,
+ SourceLocation RParenLoc);
Expr *getAssertExpr() { return AssertExpr; }
const Expr *getAssertExpr() const { return AssertExpr; }
@@ -2268,6 +2426,13 @@ public:
StringLiteral *getMessage() { return Message; }
const StringLiteral *getMessage() const { return Message; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(getLocation(), getRParenLoc());
+ }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(StaticAssertDecl *D) { return true; }
static bool classofKind(Kind K) { return K == StaticAssert; }
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 20d6da19b8ca..b84e5bba86b7 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -98,6 +98,17 @@ public:
return FriendLoc;
}
+ /// Retrieves the source range for the friend declaration.
+ SourceRange getSourceRange() const {
+ /* FIXME: consider the case of templates wrt start of range. */
+ if (NamedDecl *ND = getFriendDecl())
+ return SourceRange(getFriendLoc(), ND->getLocEnd());
+ else if (TypeSourceInfo *TInfo = getFriendType())
+ return SourceRange(getFriendLoc(), TInfo->getTypeLoc().getEndLoc());
+ else
+ return SourceRange(getFriendLoc(), getLocation());
+ }
+
/// Determines if this friend kind is unsupported.
bool isUnsupportedFriend() const {
return UnsupportedFriend;
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index b3ca474fcc19..0a4d864cd867 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -112,17 +112,20 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
public:
enum ImplementationControl { None, Required, Optional };
private:
- /// Bitfields must be first fields in this class so they pack with those
- /// declared in class Decl.
+ // The conventional meaning of this method; an ObjCMethodFamily.
+ // This is not serialized; instead, it is computed on demand and
+ // cached.
+ mutable unsigned Family : ObjCMethodFamilyBitWidth;
+
/// instance (true) or class (false) method.
- bool IsInstance : 1;
- bool IsVariadic : 1;
+ unsigned IsInstance : 1;
+ unsigned IsVariadic : 1;
// Synthesized declaration method for a property setter/getter
- bool IsSynthesized : 1;
+ unsigned IsSynthesized : 1;
// Method has a definition.
- bool IsDefined : 1;
+ unsigned IsDefined : 1;
// NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
/// @required/@optional
@@ -170,7 +173,7 @@ private:
ImplementationControl impControl = None,
unsigned numSelectorArgs = 0)
: NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
- DeclContext(ObjCMethod),
+ DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
IsInstance(isInstance), IsVariadic(isVariadic),
IsSynthesized(isSynthesized),
IsDefined(isDefined),
@@ -279,6 +282,9 @@ public:
ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
+ /// Determines the family of this method.
+ ObjCMethodFamily getMethodFamily() const;
+
bool isInstanceMethod() const { return IsInstance; }
void setInstanceMethod(bool isInst) { IsInstance = isInst; }
bool isVariadic() const { return IsVariadic; }
@@ -453,7 +459,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl {
///
/// Categories are stored as a linked list in the AST, since the categories
/// and class extensions come long after the initial interface declaration,
- /// and we avoid dynamically-resized arrays in the AST whereever possible.
+ /// and we avoid dynamically-resized arrays in the AST wherever possible.
ObjCCategoryDecl *CategoryList;
/// IvarList - List of all ivars defined by this class; including class
@@ -701,15 +707,18 @@ public:
};
private:
- ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation L, IdentifierInfo *Id,
+ ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
bool synthesized)
- : FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
- NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
+ : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
+ /*Mutable=*/false),
+ NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
- SourceLocation L, IdentifierInfo *Id, QualType T,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW = NULL,
bool synthesized=false);
@@ -753,17 +762,18 @@ private:
/// @defs(...).
class ObjCAtDefsFieldDecl : public FieldDecl {
private:
- ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+ ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, Expr *BW)
- : FieldDecl(ObjCAtDefsField, DC, L, Id, T,
+ : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
/*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
BW, /*Mutable=*/false) {}
public:
static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- IdentifierInfo *Id, QualType T,
- Expr *BW);
+ SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ QualType T, Expr *BW);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -773,7 +783,7 @@ public:
/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
/// declare a pure abstract type (i.e no instance variables are permitted).
-/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
+/// Protocols originally drew inspiration from C++ pure virtual functions (a C++
/// feature with nice semantics and lousy syntax:-). Here is an example:
///
/// @protocol NSDraggingInfo <refproto1, refproto2>
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index f41859c85790..ddbe344cdffd 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -771,9 +771,20 @@ protected:
/// \brief Data that is common to all of the declarations of a given
/// function template.
struct Common : CommonBase {
+ Common() : InjectedArgs(0) { }
+
/// \brief The function template specializations for this function
/// template, including explicit specializations and instantiations.
llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+
+ /// \brief The set of "injected" template arguments used within this
+ /// function template.
+ ///
+ /// This pointer refers to the template arguments (there are as
+ /// many template arguments as template parameaters) for the function
+ /// template, and is allocated lazily, since most function templates do not
+ /// require the use of this information.
+ TemplateArgument *InjectedArgs;
};
FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
@@ -793,6 +804,13 @@ protected:
llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
return getCommonPtr()->Specializations;
}
+
+ /// \brief Add a specialization of this function template.
+ ///
+ /// \param InsertPos Insert position in the FoldingSet, must have been
+ /// retrieved by an earlier call to findSpecialization().
+ void addSpecialization(FunctionTemplateSpecializationInfo* Info,
+ void *InsertPos);
public:
/// Get the underlying function declaration of the template.
@@ -844,13 +862,25 @@ public:
return makeSpecIterator(getSpecializations(), true);
}
- /// Create a template function node.
+ /// \brief Retrieve the "injected" template arguments that correspond to the
+ /// template parameters of this function template.
+ ///
+ /// Although the C++ standard has no notion of the "injected" template
+ /// arguments for a function template, the notion is convenient when
+ /// we need to perform substitutions inside the definition of a function
+ /// template.
+ std::pair<const TemplateArgument *, unsigned> getInjectedTemplateArgs();
+
+ /// \brief Create a function template node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl);
+ /// \brief Create an empty function template node.
+ static FunctionTemplateDecl *Create(ASTContext &C, EmptyShell);
+
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FunctionTemplateDecl *D) { return true; }
@@ -915,25 +945,23 @@ class TemplateTypeParmDecl : public TypeDecl {
/// default argument.
bool InheritedDefault : 1;
- /// \brief Whether this is a parameter pack.
- bool ParameterPack : 1;
-
/// \brief The default template argument, if any.
TypeSourceInfo *DefaultArgument;
- TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- bool Typename, QualType Type, bool ParameterPack)
- : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
- InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
- TypeForDecl = Type.getTypePtrOrNull();
- }
+ TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ bool Typename)
+ : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
+ InheritedDefault(false), DefaultArgument() { }
/// Sema creates these on the stack during auto type deduction.
friend class Sema;
public:
static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation L, unsigned D, unsigned P,
+ SourceLocation KeyLoc,
+ SourceLocation NameLoc,
+ unsigned D, unsigned P,
IdentifierInfo *Id, bool Typename,
bool ParameterPack);
static TemplateTypeParmDecl *Create(const ASTContext &C, EmptyShell Empty);
@@ -978,9 +1006,6 @@ public:
/// the 'typename' or 'class' keyword.
void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
- /// \brief Set whether this is a parameter pack.
- void setParameterPack(bool isParamPack) { ParameterPack = isParamPack; }
-
/// \brief Retrieve the depth of the template parameter.
unsigned getDepth() const;
@@ -988,7 +1013,9 @@ public:
unsigned getIndex() const;
/// \brief Returns whether this is a parameter pack.
- bool isParameterPack() const { return ParameterPack; }
+ bool isParameterPack() const;
+
+ SourceRange getSourceRange() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -1021,17 +1048,19 @@ class NonTypeTemplateParmDecl
/// \brief The number of types in an expanded parameter pack.
unsigned NumExpandedTypes;
- NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
- unsigned P, IdentifierInfo *Id, QualType T,
+ NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, unsigned D, unsigned P,
+ IdentifierInfo *Id, QualType T,
bool ParameterPack, TypeSourceInfo *TInfo)
- : DeclaratorDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo),
+ : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
ParameterPack(ParameterPack), ExpandedParameterPack(false),
NumExpandedTypes(0)
{ }
- NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
- unsigned P, IdentifierInfo *Id, QualType T,
+ NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, unsigned D, unsigned P,
+ IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
const QualType *ExpandedTypes,
unsigned NumExpandedTypes,
@@ -1041,13 +1070,14 @@ class NonTypeTemplateParmDecl
public:
static NonTypeTemplateParmDecl *
- Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
- unsigned P, IdentifierInfo *Id, QualType T, bool ParameterPack,
- TypeSourceInfo *TInfo);
+ Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
+ QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
static NonTypeTemplateParmDecl *
- Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
- unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+ Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
+ QualType T, TypeSourceInfo *TInfo,
const QualType *ExpandedTypes, unsigned NumExpandedTypes,
TypeSourceInfo **ExpandedTInfos);
@@ -1057,7 +1087,6 @@ public:
using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;
- SourceLocation getInnerLocStart() const;
SourceRange getSourceRange() const;
/// \brief Determine whether this template parameter has a default
@@ -1316,7 +1345,8 @@ class ClassTemplateSpecializationDecl
protected:
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
- DeclContext *DC, SourceLocation L,
+ DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc,
ClassTemplateDecl *SpecializedTemplate,
const TemplateArgument *Args,
unsigned NumArgs,
@@ -1326,7 +1356,8 @@ protected:
public:
static ClassTemplateSpecializationDecl *
- Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
+ Create(ASTContext &Context, TagKind TK, DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation IdLoc,
ClassTemplateDecl *SpecializedTemplate,
const TemplateArgument *Args,
unsigned NumArgs,
@@ -1488,7 +1519,7 @@ public:
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
}
- SourceLocation getInnerLocStart() const { return getTemplateKeywordLoc(); }
+ SourceRange getSourceRange() const;
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
@@ -1544,7 +1575,9 @@ class ClassTemplatePartialSpecializationDecl
InstantiatedFromMember;
ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
- DeclContext *DC, SourceLocation L,
+ DeclContext *DC,
+ SourceLocation StartLoc,
+ SourceLocation IdLoc,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
const TemplateArgument *Args,
@@ -1552,14 +1585,7 @@ class ClassTemplatePartialSpecializationDecl
TemplateArgumentLoc *ArgInfos,
unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl,
- unsigned SequenceNumber)
- : ClassTemplateSpecializationDecl(Context,
- ClassTemplatePartialSpecialization,
- TK, DC, L, SpecializedTemplate,
- Args, NumArgs, PrevDecl),
- TemplateParams(Params), ArgsAsWritten(ArgInfos),
- NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
- InstantiatedFromMember(0, false) { }
+ unsigned SequenceNumber);
ClassTemplatePartialSpecializationDecl()
: ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
@@ -1569,7 +1595,8 @@ class ClassTemplatePartialSpecializationDecl
public:
static ClassTemplatePartialSpecializationDecl *
- Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
+ Create(ASTContext &Context, TagKind TK,DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation IdLoc,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
const TemplateArgument *Args,
@@ -1742,6 +1769,10 @@ protected:
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
+ ClassTemplateDecl(EmptyShell Empty)
+ : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
+ DeclarationName(), 0, 0) { }
+
CommonBase *newCommon(ASTContext &C);
Common *getCommonPtr() {
@@ -1768,6 +1799,9 @@ public:
NamedDecl *Decl,
ClassTemplateDecl *PrevDecl);
+ /// Create an empty class template node.
+ static ClassTemplateDecl *Create(ASTContext &C, EmptyShell);
+
/// \brief Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
ClassTemplateSpecializationDecl *
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
index 035f57c12ea7..bab1606dcee4 100644
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ b/include/clang/AST/EvaluatedExprVisitor.h
@@ -37,7 +37,8 @@ public:
// other sub-expressions).
void VisitDeclRefExpr(DeclRefExpr *E) { }
void VisitOffsetOfExpr(OffsetOfExpr *E) { }
- void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { }
+ void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { }
+ void VisitExpressionTraitExpr(ExpressionTraitExpr *E) { }
void VisitBlockExpr(BlockExpr *E) { }
void VisitCXXUuidofExpr(CXXUuidofExpr *E) { }
void VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { }
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 95bfad5a16c2..5f2d144eb544 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -21,12 +21,12 @@
#include "clang/AST/OperationKinds.h"
#include "clang/AST/ASTVector.h"
#include "clang/AST/UsuallyTinyPtrVector.h"
+#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <cctype>
-#include <vector>
namespace clang {
class ASTContext;
@@ -172,6 +172,7 @@ public:
LV_IncompleteVoidType,
LV_DuplicateVectorComponents,
LV_InvalidExpression,
+ LV_InvalidMessageExpression,
LV_MemberFunction,
LV_SubObjCPropertySetting,
LV_ClassTemporary
@@ -203,6 +204,7 @@ public:
MLV_NoSetterProperty,
MLV_MemberFunction,
MLV_SubObjCPropertySetting,
+ MLV_InvalidMessageExpression,
MLV_ClassTemporary
};
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
@@ -218,10 +220,12 @@ public:
CL_XValue,
CL_Function, // Functions cannot be lvalues in C.
CL_Void, // Void cannot be an lvalue in C.
+ CL_AddressableVoid, // Void expression whose address can be taken in C.
CL_DuplicateVectorComponents, // A vector shuffle with dupes.
CL_MemberFunction, // An expression referring to a member function
CL_SubObjCPropertySetting,
CL_ClassTemporary, // A prvalue of class type
+ CL_ObjCMessageRValue, // ObjC message is an rvalue
CL_PRValue // A prvalue for any other reason, of any other type
};
/// \brief The results of modification testing.
@@ -482,6 +486,11 @@ public:
/// \brief Returns true if this expression is a bound member function.
bool isBoundMemberFunction(ASTContext &Ctx) const;
+ /// \brief Given an expression of bound-member type, find the type
+ /// of the member. Returns null if this is an *overloaded* bound
+ /// member expression.
+ static QualType findBoundMemberType(const Expr *expr);
+
/// \brief Result type of CanThrow().
enum CanThrowResult {
CT_Cannot,
@@ -536,6 +545,9 @@ public:
/// temporary object of the given class type.
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const;
+ /// \brief Whether this expression is an implicit reference to 'this' in C++.
+ bool isImplicitCXXThis() const;
+
const Expr *IgnoreParens() const {
return const_cast<Expr*>(this)->IgnoreParens();
}
@@ -618,16 +630,6 @@ public:
static bool classof(const OpaqueValueExpr *) { return true; }
};
-/// \brief Represents the qualifier that may precede a C++ name, e.g., the
-/// "std::" in "std::sort".
-struct NameQualifier {
- /// \brief The nested name specifier.
- NestedNameSpecifier *NNS;
-
- /// \brief The source range covered by the nested name specifier.
- SourceRange Range;
-};
-
/// \brief Represents an explicit template argument list in C++, e.g.,
/// the "<int>" in "sort<int>".
struct ExplicitTemplateArgumentList {
@@ -659,95 +661,118 @@ struct ExplicitTemplateArgumentList {
static std::size_t sizeFor(unsigned NumTemplateArgs);
static std::size_t sizeFor(const TemplateArgumentListInfo &List);
};
-
-/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
-/// enum, etc.
+
+/// \brief A reference to a declared variable, function, enum, etc.
+/// [C99 6.5.1p2]
+///
+/// This encodes all the information about how a declaration is referenced
+/// within an expression.
+///
+/// There are several optional constructs attached to DeclRefExprs only when
+/// they apply in order to conserve memory. These are laid out past the end of
+/// the object, and flags in the DeclRefExprBitfield track whether they exist:
+///
+/// DeclRefExprBits.HasQualifier:
+/// Specifies when this declaration reference expression has a C++
+/// nested-name-specifier.
+/// DeclRefExprBits.HasFoundDecl:
+/// Specifies when this declaration reference expression has a record of
+/// a NamedDecl (different from the referenced ValueDecl) which was found
+/// during name lookup and/or overload resolution.
+/// DeclRefExprBits.HasExplicitTemplateArgs:
+/// Specifies when this declaration reference expression has an explicit
+/// C++ template argument list.
class DeclRefExpr : public Expr {
- enum {
- // Flag on DecoratedD that specifies when this declaration reference
- // expression has a C++ nested-name-specifier.
- HasQualifierFlag = 0x01,
- // Flag on DecoratedD that specifies when this declaration reference
- // expression has an explicit C++ template argument list.
- HasExplicitTemplateArgumentListFlag = 0x02
- };
-
- // DecoratedD - The declaration that we are referencing, plus two bits to
- // indicate whether (1) the declaration's name was explicitly qualified and
- // (2) the declaration's name was followed by an explicit template
- // argument list.
- llvm::PointerIntPair<ValueDecl *, 2> DecoratedD;
+ /// \brief The declaration that we are referencing.
+ ValueDecl *D;
- // Loc - The location of the declaration name itself.
+ /// \brief The location of the declaration name itself.
SourceLocation Loc;
- /// DNLoc - Provides source/type location info for the
- /// declaration name embedded in DecoratedD.
+ /// \brief Provides source/type location info for the declaration name
+ /// embedded in D.
DeclarationNameLoc DNLoc;
- /// \brief Retrieve the qualifier that preceded the declaration name, if any.
- NameQualifier *getNameQualifier() {
- if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
- return 0;
-
- return reinterpret_cast<NameQualifier *> (this + 1);
+ /// \brief Helper to retrieve the optional NestedNameSpecifierLoc.
+ NestedNameSpecifierLoc &getInternalQualifierLoc() {
+ assert(hasQualifier());
+ return *reinterpret_cast<NestedNameSpecifierLoc *>(this + 1);
}
-
- /// \brief Retrieve the qualifier that preceded the member name, if any.
- const NameQualifier *getNameQualifier() const {
- return const_cast<DeclRefExpr *>(this)->getNameQualifier();
+
+ /// \brief Helper to retrieve the optional NestedNameSpecifierLoc.
+ const NestedNameSpecifierLoc &getInternalQualifierLoc() const {
+ return const_cast<DeclRefExpr *>(this)->getInternalQualifierLoc();
}
- DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
- ValueDecl *D, SourceLocation NameLoc,
- const TemplateArgumentListInfo *TemplateArgs,
- QualType T, ExprValueKind VK);
+ /// \brief Test whether there is a distinct FoundDecl attached to the end of
+ /// this DRE.
+ bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
- DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+ /// \brief Helper to retrieve the optional NamedDecl through which this
+ /// reference occured.
+ NamedDecl *&getInternalFoundDecl() {
+ assert(hasFoundDecl());
+ if (hasQualifier())
+ return *reinterpret_cast<NamedDecl **>(&getInternalQualifierLoc() + 1);
+ return *reinterpret_cast<NamedDecl **>(this + 1);
+ }
+
+ /// \brief Helper to retrieve the optional NamedDecl through which this
+ /// reference occured.
+ NamedDecl *getInternalFoundDecl() const {
+ return const_cast<DeclRefExpr *>(this)->getInternalFoundDecl();
+ }
+
+ DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
ValueDecl *D, const DeclarationNameInfo &NameInfo,
+ NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK);
/// \brief Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty)
: Expr(DeclRefExprClass, Empty) { }
-
+
/// \brief Computes the type- and value-dependence flags for this
/// declaration reference expression.
void computeDependence();
public:
- DeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK, SourceLocation l) :
- Expr(DeclRefExprClass, t, VK, OK_Ordinary, false, false, false),
- DecoratedD(d, 0), Loc(l) {
+ DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L)
+ : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false),
+ D(D), Loc(L) {
+ DeclRefExprBits.HasQualifier = 0;
+ DeclRefExprBits.HasExplicitTemplateArgs = 0;
+ DeclRefExprBits.HasFoundDecl = 0;
computeDependence();
}
static DeclRefExpr *Create(ASTContext &Context,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
+ NestedNameSpecifierLoc QualifierLoc,
ValueDecl *D,
SourceLocation NameLoc,
QualType T, ExprValueKind VK,
+ NamedDecl *FoundD = 0,
const TemplateArgumentListInfo *TemplateArgs = 0);
static DeclRefExpr *Create(ASTContext &Context,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
+ NestedNameSpecifierLoc QualifierLoc,
ValueDecl *D,
const DeclarationNameInfo &NameInfo,
QualType T, ExprValueKind VK,
+ NamedDecl *FoundD = 0,
const TemplateArgumentListInfo *TemplateArgs = 0);
/// \brief Construct an empty declaration reference expression.
static DeclRefExpr *CreateEmpty(ASTContext &Context,
- bool HasQualifier,
+ bool HasQualifier,
+ bool HasFoundDecl,
bool HasExplicitTemplateArgs,
unsigned NumTemplateArgs);
-
- ValueDecl *getDecl() { return DecoratedD.getPointer(); }
- const ValueDecl *getDecl() const { return DecoratedD.getPointer(); }
- void setDecl(ValueDecl *NewD) { DecoratedD.setPointer(NewD); }
+
+ ValueDecl *getDecl() { return D; }
+ const ValueDecl *getDecl() const { return D; }
+ void setDecl(ValueDecl *NewD) { D = NewD; }
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc);
@@ -759,43 +784,62 @@ public:
/// \brief Determine whether this declaration reference was preceded by a
/// C++ nested-name-specifier, e.g., \c N::foo.
- bool hasQualifier() const { return DecoratedD.getInt() & HasQualifierFlag; }
-
- /// \brief If the name was qualified, retrieves the source range of
- /// the nested-name-specifier that precedes the name. Otherwise,
- /// returns an empty source range.
- SourceRange getQualifierRange() const {
- if (!hasQualifier())
- return SourceRange();
-
- return getNameQualifier()->Range;
- }
-
- /// \brief If the name was qualified, retrieves the nested-name-specifier
+ bool hasQualifier() const { return DeclRefExprBits.HasQualifier; }
+
+ /// \brief If the name was qualified, retrieves the nested-name-specifier
/// that precedes the name. Otherwise, returns NULL.
NestedNameSpecifier *getQualifier() const {
if (!hasQualifier())
return 0;
-
- return getNameQualifier()->NNS;
+
+ return getInternalQualifierLoc().getNestedNameSpecifier();
}
-
+
+ /// \brief If the name was qualified, retrieves the nested-name-specifier
+ /// that precedes the name, with source-location information.
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ if (!hasQualifier())
+ return NestedNameSpecifierLoc();
+
+ return getInternalQualifierLoc();
+ }
+
+ /// \brief Get the NamedDecl through which this reference occured.
+ ///
+ /// This Decl may be different from the ValueDecl actually referred to in the
+ /// presence of using declarations, etc. It always returns non-NULL, and may
+ /// simple return the ValueDecl when appropriate.
+ NamedDecl *getFoundDecl() {
+ return hasFoundDecl() ? getInternalFoundDecl() : D;
+ }
+
+ /// \brief Get the NamedDecl through which this reference occurred.
+ /// See non-const variant.
+ const NamedDecl *getFoundDecl() const {
+ return hasFoundDecl() ? getInternalFoundDecl() : D;
+ }
+
+ /// \brief Determines whether this declaration reference was followed by an
+ /// explict template argument list.
bool hasExplicitTemplateArgs() const {
- return (DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag);
+ return DeclRefExprBits.HasExplicitTemplateArgs;
}
-
+
/// \brief Retrieve the explicit template argument list that followed the
/// member template name.
ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
assert(hasExplicitTemplateArgs());
+ if (hasFoundDecl())
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(
+ &getInternalFoundDecl() + 1);
- if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
- return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
-
- return *reinterpret_cast<ExplicitTemplateArgumentList *>(
- getNameQualifier() + 1);
+ if (hasQualifier())
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(
+ &getInternalQualifierLoc() + 1);
+
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
}
-
+
/// \brief Retrieve the explicit template argument list that followed the
/// member template name.
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
@@ -809,50 +853,50 @@ public:
if (!hasExplicitTemplateArgs()) return 0;
return &getExplicitTemplateArgs();
}
-
+
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs())
getExplicitTemplateArgs().copyInto(List);
}
-
+
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
if (!hasExplicitTemplateArgs())
return SourceLocation();
-
+
return getExplicitTemplateArgs().LAngleLoc;
}
-
+
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
return 0;
-
+
return getExplicitTemplateArgs().getTemplateArgs();
}
-
+
/// \brief Retrieve the number of template arguments provided as part of this
/// template-id.
unsigned getNumTemplateArgs() const {
if (!hasExplicitTemplateArgs())
return 0;
-
+
return getExplicitTemplateArgs().NumTemplateArgs;
}
-
+
/// \brief Retrieve the location of the right angle bracket following the
/// template arguments ('>').
SourceLocation getRAngleLoc() const {
if (!hasExplicitTemplateArgs())
return SourceLocation();
-
+
return getExplicitTemplateArgs().RAngleLoc;
}
-
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclRefExprClass;
}
@@ -860,7 +904,7 @@ public:
// Iterators
child_range children() { return child_range(); }
-
+
friend class ASTStmtReader;
friend class ASTStmtWriter;
};
@@ -1133,9 +1177,12 @@ public:
/// In this case, getByteLength() will return 6, but the string literal will
/// have type "char[2]".
class StringLiteral : public Expr {
+ friend class ASTStmtReader;
+
const char *StrData;
unsigned ByteLength;
bool IsWide;
+ bool IsPascal;
unsigned NumConcatenated;
SourceLocation TokLocs[1];
@@ -1146,14 +1193,15 @@ 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, QualType Ty,
+ unsigned ByteLength, 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, QualType Ty, SourceLocation Loc) {
- return Create(C, StrData, ByteLength, Wide, Ty, &Loc, 1);
+ unsigned ByteLength, bool Wide,
+ bool Pascal, QualType Ty, SourceLocation Loc) {
+ return Create(C, StrData, ByteLength, Wide, Pascal, Ty, &Loc, 1);
}
/// \brief Construct an empty string literal.
@@ -1169,8 +1217,8 @@ public:
void setString(ASTContext &C, llvm::StringRef Str);
bool isWide() const { return IsWide; }
- void setWide(bool W) { IsWide = W; }
-
+ bool isPascal() const { return IsPascal; }
+
bool containsNonAsciiOrNull() const {
llvm::StringRef Str = getString();
for (unsigned i = 0, e = Str.size(); i != e; ++i)
@@ -1458,7 +1506,7 @@ public:
/// the square brackets. For a field or identifier node, the source range
/// contains the location of the period (if there is one) and the
/// identifier.
- SourceRange getRange() const { return Range; }
+ SourceRange getSourceRange() const { return Range; }
};
private:
@@ -1556,10 +1604,11 @@ public:
}
};
-/// SizeOfAlignOfExpr - [C99 6.5.3.4] - This is for sizeof/alignof, both of
-/// types and expressions.
-class SizeOfAlignOfExpr : public Expr {
- bool isSizeof : 1; // true if sizeof, false if alignof.
+/// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated)
+/// expression operand. Used for sizeof/alignof (C99 6.5.3.4) and
+/// vec_step (OpenCL 1.1 6.11.12).
+class UnaryExprOrTypeTraitExpr : public Expr {
+ unsigned Kind : 2;
bool isType : 1; // true if operand is a type, false if an expression
union {
TypeSourceInfo *Ty;
@@ -1568,36 +1617,38 @@ class SizeOfAlignOfExpr : public Expr {
SourceLocation OpLoc, RParenLoc;
public:
- SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo,
- QualType resultType, SourceLocation op,
- SourceLocation rp) :
- Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary,
+ UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo,
+ QualType resultType, SourceLocation op,
+ SourceLocation rp) :
+ Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
TInfo->getType()->isDependentType(),
TInfo->getType()->containsUnexpandedParameterPack()),
- isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) {
+ Kind(ExprKind), isType(true), OpLoc(op), RParenLoc(rp) {
Argument.Ty = TInfo;
}
- SizeOfAlignOfExpr(bool issizeof, Expr *E,
- QualType resultType, SourceLocation op,
- SourceLocation rp) :
- Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary,
+ UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E,
+ QualType resultType, SourceLocation op,
+ SourceLocation rp) :
+ Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
E->isTypeDependent(),
E->containsUnexpandedParameterPack()),
- isSizeof(issizeof), isType(false), OpLoc(op), RParenLoc(rp) {
+ Kind(ExprKind), isType(false), OpLoc(op), RParenLoc(rp) {
Argument.Ex = E;
}
/// \brief Construct an empty sizeof/alignof expression.
- explicit SizeOfAlignOfExpr(EmptyShell Empty)
- : Expr(SizeOfAlignOfExprClass, Empty) { }
+ explicit UnaryExprOrTypeTraitExpr(EmptyShell Empty)
+ : Expr(UnaryExprOrTypeTraitExprClass, Empty) { }
- bool isSizeOf() const { return isSizeof; }
- void setSizeof(bool S) { isSizeof = S; }
+ UnaryExprOrTypeTrait getKind() const {
+ return static_cast<UnaryExprOrTypeTrait>(Kind);
+ }
+ void setKind(UnaryExprOrTypeTrait K) { Kind = K; }
bool isArgumentType() const { return isType; }
QualType getArgumentType() const {
@@ -1612,7 +1663,7 @@ public:
return static_cast<Expr*>(Argument.Ex);
}
const Expr *getArgumentExpr() const {
- return const_cast<SizeOfAlignOfExpr*>(this)->getArgumentExpr();
+ return const_cast<UnaryExprOrTypeTraitExpr*>(this)->getArgumentExpr();
}
void setArgument(Expr *E) { Argument.Ex = E; isType = false; }
@@ -1638,9 +1689,9 @@ public:
}
static bool classof(const Stmt *T) {
- return T->getStmtClass() == SizeOfAlignOfExprClass;
+ return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
}
- static bool classof(const SizeOfAlignOfExpr *) { return true; }
+ static bool classof(const UnaryExprOrTypeTraitExpr *) { return true; }
// Iterators
child_range children();
@@ -1862,7 +1913,13 @@ public:
///
class MemberExpr : public Expr {
/// Extra data stored in some member expressions.
- struct MemberNameQualifier : public NameQualifier {
+ struct MemberNameQualifier {
+ /// \brief The nested-name-specifier that qualifies the name, including
+ /// source-location information.
+ NestedNameSpecifierLoc QualifierLoc;
+
+ /// \brief The DeclAccessPair through which the MemberDecl was found due to
+ /// name qualifiers.
DeclAccessPair FoundDecl;
};
@@ -1936,7 +1993,7 @@ public:
HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {}
static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
- NestedNameSpecifier *qual, SourceRange qualrange,
+ NestedNameSpecifierLoc QualifierLoc,
ValueDecl *memberdecl, DeclAccessPair founddecl,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *targs,
@@ -1965,16 +2022,6 @@ public:
/// x->Base::foo.
bool hasQualifier() const { return getQualifier() != 0; }
- /// \brief If the member name was qualified, retrieves the source range of
- /// the nested-name-specifier that precedes the member name. Otherwise,
- /// returns an empty source range.
- SourceRange getQualifierRange() const {
- if (!HasQualifierOrFoundDecl)
- return SourceRange();
-
- return getMemberQualifier()->Range;
- }
-
/// \brief If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// NULL.
@@ -1982,7 +2029,17 @@ public:
if (!HasQualifierOrFoundDecl)
return 0;
- return getMemberQualifier()->NNS;
+ return getMemberQualifier()->QualifierLoc.getNestedNameSpecifier();
+ }
+
+ /// \brief If the member name was qualified, retrieves the
+ /// nested-name-specifier that precedes the member name, with source-location
+ /// information.
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ if (!hasQualifier())
+ return NestedNameSpecifierLoc();
+
+ return getMemberQualifier()->QualifierLoc;
}
/// \brief Determines whether this member expression actually had a C++
@@ -2075,20 +2132,15 @@ public:
SourceLocation getMemberLoc() const { return MemberLoc; }
void setMemberLoc(SourceLocation L) { MemberLoc = L; }
- SourceRange getSourceRange() const {
- // If we have an implicit base (like a C++ implicit this),
- // make sure not to return its location
- SourceLocation EndLoc = (HasExplicitTemplateArgumentList)
- ? getRAngleLoc() : getMemberNameInfo().getEndLoc();
-
- SourceLocation BaseLoc = getBase()->getLocStart();
- if (BaseLoc.isInvalid())
- return SourceRange(MemberLoc, EndLoc);
- return SourceRange(BaseLoc, EndLoc);
- }
-
+ SourceRange getSourceRange() const;
+
SourceLocation getExprLoc() const { return MemberLoc; }
+ /// \brief Determine whether the base of this explicit is implicit.
+ bool isImplicitAccess() const {
+ return getBase() && getBase()->isImplicitCXXThis();
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == MemberExprClass;
}
@@ -2234,6 +2286,12 @@ private:
}
CXXBaseSpecifier **path_buffer();
+ void setBasePathSize(unsigned basePathSize) {
+ CastExprBits.BasePathSize = basePathSize;
+ assert(CastExprBits.BasePathSize == basePathSize &&
+ "basePathSize doesn't fit in bits of CastExprBits.BasePathSize!");
+ }
+
protected:
CastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
const CastKind kind, Expr *op, unsigned BasePathSize) :
@@ -2249,14 +2307,14 @@ protected:
Op(op) {
assert(kind != CK_Invalid && "creating cast with invalid cast kind");
CastExprBits.Kind = kind;
- CastExprBits.BasePathSize = BasePathSize;
+ setBasePathSize(BasePathSize);
CheckCastConsistency();
}
/// \brief Construct an empty cast.
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
: Expr(SC, Empty) {
- CastExprBits.BasePathSize = BasePathSize;
+ setBasePathSize(BasePathSize);
}
public:
@@ -3173,9 +3231,14 @@ class InitListExpr : public Expr {
/// written in the source code.
InitListExpr *SyntacticForm;
- /// If this initializer list initializes a union, specifies which
- /// field within the union will be initialized.
- FieldDecl *UnionFieldInit;
+ /// \brief Either:
+ /// If this initializer list initializes an array with more elements than
+ /// there are initializers in the list, specifies an expression to be used
+ /// for value initialization of the rest of the elements.
+ /// Or
+ /// If this initializer list initializes a union, specifies which
+ /// field within the union will be initialized.
+ llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
/// Whether this initializer list originally had a GNU array-range
/// designator in it. This is a temporary marker used by CodeGen.
@@ -3227,17 +3290,29 @@ public:
///
/// When @p Init is out of range for this initializer list, the
/// initializer list will be extended with NULL expressions to
- /// accomodate the new entry.
+ /// accommodate the new entry.
Expr *updateInit(ASTContext &C, unsigned Init, Expr *expr);
+ /// \brief If this initializer list initializes an array with more elements
+ /// than there are initializers in the list, specifies an expression to be
+ /// used for value initialization of the rest of the elements.
+ Expr *getArrayFiller() {
+ return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
+ }
+ void setArrayFiller(Expr *filler);
+
/// \brief If this initializes a union, specifies which field in the
/// union to initialize.
///
/// Typically, this field is the first named field within the
/// union. However, a designated initializer can specify the
/// initialization of a different field within the union.
- FieldDecl *getInitializedFieldInUnion() { return UnionFieldInit; }
- void setInitializedFieldInUnion(FieldDecl *FD) { UnionFieldInit = FD; }
+ FieldDecl *getInitializedFieldInUnion() {
+ return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
+ }
+ void setInitializedFieldInUnion(FieldDecl *FD) {
+ ArrayFillerOrUnionFieldInit = FD;
+ }
// Explicit InitListExpr's originate from source code (and have valid source
// locations). Implicit InitListExpr's are created by the semantic analyzer.
@@ -3288,6 +3363,9 @@ public:
const_reverse_iterator rbegin() const { return InitExprs.rbegin(); }
reverse_iterator rend() { return InitExprs.rend(); }
const_reverse_iterator rend() const { return InitExprs.rend(); }
+
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
};
/// @brief Represents a C99 designated initializer expression.
@@ -3492,6 +3570,12 @@ public:
else
return getLBracketLoc();
}
+ SourceLocation getEndLocation() const {
+ return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
+ }
+ SourceRange getSourceRange() const {
+ return SourceRange(getStartLocation(), getEndLocation());
+ }
};
static DesignatedInitExpr *Create(ASTContext &C, Designator *Designators,
@@ -3574,6 +3658,8 @@ public:
void ExpandDesignator(ASTContext &C, unsigned Idx, const Designator *First,
const Designator *Last);
+ SourceRange getDesignatorsSourceRange() const;
+
SourceRange getSourceRange() const;
static bool classof(const Stmt *T) {
@@ -3667,6 +3753,118 @@ public:
};
+/// \brief Represents a C1X generic selection.
+///
+/// A generic selection (C1X 6.5.1.1) contains an unevaluated controlling
+/// expression, followed by one or more generic associations. Each generic
+/// association specifies a type name and an expression, or "default" and an
+/// expression (in which case it is known as a default generic association).
+/// The type and value of the generic selection are identical to those of its
+/// result expression, which is defined as the expression in the generic
+/// association with a type name that is compatible with the type of the
+/// controlling expression, or the expression in the default generic association
+/// if no types are compatible. For example:
+///
+/// @code
+/// _Generic(X, double: 1, float: 2, default: 3)
+/// @endcode
+///
+/// The above expression evaluates to 1 if 1.0 is substituted for X, 2 if 1.0f
+/// or 3 if "hello".
+///
+/// As an extension, generic selections are allowed in C++, where the following
+/// additional semantics apply:
+///
+/// Any generic selection whose controlling expression is type-dependent or
+/// which names a dependent type in its association list is result-dependent,
+/// which means that the choice of result expression is dependent.
+/// Result-dependent generic associations are both type- and value-dependent.
+class GenericSelectionExpr : public Expr {
+ enum { CONTROLLING, END_EXPR };
+ TypeSourceInfo **AssocTypes;
+ Stmt **SubExprs;
+ unsigned NumAssocs, ResultIndex;
+ SourceLocation GenericLoc, DefaultLoc, RParenLoc;
+
+public:
+ GenericSelectionExpr(ASTContext &Context,
+ SourceLocation GenericLoc, Expr *ControllingExpr,
+ TypeSourceInfo **AssocTypes, Expr **AssocExprs,
+ unsigned NumAssocs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack,
+ unsigned ResultIndex);
+
+ /// This constructor is used in the result-dependent case.
+ GenericSelectionExpr(ASTContext &Context,
+ SourceLocation GenericLoc, Expr *ControllingExpr,
+ TypeSourceInfo **AssocTypes, Expr **AssocExprs,
+ unsigned NumAssocs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack);
+
+ explicit GenericSelectionExpr(EmptyShell Empty)
+ : Expr(GenericSelectionExprClass, Empty) { }
+
+ unsigned getNumAssocs() const { return NumAssocs; }
+
+ SourceLocation getGenericLoc() const { return GenericLoc; }
+ SourceLocation getDefaultLoc() const { return DefaultLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+
+ const Expr *getAssocExpr(unsigned i) const {
+ return cast<Expr>(SubExprs[END_EXPR+i]);
+ }
+ Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); }
+
+ const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
+ return AssocTypes[i];
+ }
+ TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
+
+ QualType getAssocType(unsigned i) const {
+ if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i))
+ return TS->getType();
+ else
+ return QualType();
+ }
+
+ const Expr *getControllingExpr() const {
+ return cast<Expr>(SubExprs[CONTROLLING]);
+ }
+ Expr *getControllingExpr() { return cast<Expr>(SubExprs[CONTROLLING]); }
+
+ /// Whether this generic selection is result-dependent.
+ bool isResultDependent() const { return ResultIndex == -1U; }
+
+ /// The zero-based index of the result expression's generic association in
+ /// the generic selection's association list. Defined only if the
+ /// generic selection is not result-dependent.
+ unsigned getResultIndex() const {
+ assert(!isResultDependent() && "Generic selection is result-dependent");
+ return ResultIndex;
+ }
+
+ /// The generic selection's result expression. Defined only if the
+ /// generic selection is not result-dependent.
+ const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); }
+ Expr *getResultExpr() { return getAssocExpr(getResultIndex()); }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(GenericLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == GenericSelectionExprClass;
+ }
+ static bool classof(const GenericSelectionExpr *) { return true; }
+
+ child_range children() {
+ return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs);
+ }
+
+ friend class ASTStmtReader;
+};
+
//===----------------------------------------------------------------------===//
// Clang Extensions
//===----------------------------------------------------------------------===//
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 225db3c11fd0..a97057973745 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_EXPRCXX_H
#include "clang/Basic/TypeTraits.h"
+#include "clang/Basic/ExpressionTraits.h"
#include "clang/AST/Expr.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/AST/TemplateBase.h"
@@ -99,7 +100,10 @@ public:
/// getImplicitObjectArgument - Retrieves the implicit object
/// argument for the member call. For example, in "x.f(5)", this
/// operation would return "x".
- Expr *getImplicitObjectArgument();
+ Expr *getImplicitObjectArgument() const;
+
+ /// Retrieves the declaration of the called method.
+ CXXMethodDecl *getMethodDecl() const;
/// getRecordDecl - Retrieves the CXXRecordDecl for the underlying type of
/// the implicit object argument. Note that this is may not be the same
@@ -250,6 +254,8 @@ public:
static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context,
unsigned pathSize);
+ bool isAlwaysNull() const;
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDynamicCastExprClass;
}
@@ -774,7 +780,8 @@ public:
enum ConstructionKind {
CK_Complete,
CK_NonVirtualBase,
- CK_VirtualBase
+ CK_VirtualBase,
+ CK_Delegating
};
private:
@@ -1080,6 +1087,17 @@ public:
TypeSourceInfo *getAllocatedTypeSourceInfo() const {
return AllocatedTypeInfo;
}
+
+ /// \brief True if the allocation result needs to be null-checked.
+ /// C++0x [expr.new]p13:
+ /// If the allocation function returns null, initialization shall
+ /// not be done, the deallocation function shall not be called,
+ /// and the value of the new-expression shall be null.
+ /// An allocation function is not allowed to return null unless it
+ /// has a non-throwing exception-specification. The '03 rule is
+ /// identical except that the definition of a non-throwing
+ /// exception specification is just "is it throw()?".
+ bool shouldNullCheckAllocation(ASTContext &Ctx) const;
FunctionDecl *getOperatorNew() const { return OperatorNew; }
void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
@@ -1577,6 +1595,122 @@ public:
friend class ASTStmtReader;
};
+/// ArrayTypeTraitExpr - An Embarcadero array type trait, as used in the
+/// implementation of __array_rank and __array_extent.
+/// Example:
+/// __array_rank(int[10][20]) == 2
+/// __array_extent(int, 1) == 20
+class ArrayTypeTraitExpr : public Expr {
+ /// ATT - The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
+ unsigned ATT : 2;
+
+ /// The value of the type trait. Unspecified if dependent.
+ uint64_t Value;
+
+ /// The array dimension being queried, or -1 if not used
+ Expr *Dimension;
+
+ /// Loc - The location of the type trait keyword.
+ SourceLocation Loc;
+
+ /// RParen - The location of the closing paren.
+ SourceLocation RParen;
+
+ /// The type being queried.
+ TypeSourceInfo *QueriedType;
+
+public:
+ ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
+ TypeSourceInfo *queried, uint64_t value,
+ Expr *dimension, SourceLocation rparen, QualType ty)
+ : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
+ false, queried->getType()->isDependentType(),
+ queried->getType()->containsUnexpandedParameterPack()),
+ ATT(att), Value(value), Dimension(dimension),
+ Loc(loc), RParen(rparen), QueriedType(queried) { }
+
+
+ explicit ArrayTypeTraitExpr(EmptyShell Empty)
+ : Expr(ArrayTypeTraitExprClass, Empty), ATT(0), Value(false),
+ QueriedType() { }
+
+ virtual ~ArrayTypeTraitExpr() { }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc, RParen); }
+
+ ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
+
+ QualType getQueriedType() const { return QueriedType->getType(); }
+
+ TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
+
+ uint64_t getValue() const { assert(!isTypeDependent()); return Value; }
+
+ Expr *getDimensionExpression() const { return Dimension; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ArrayTypeTraitExprClass;
+ }
+ static bool classof(const ArrayTypeTraitExpr *) { return true; }
+
+ // Iterators
+ child_range children() { return child_range(); }
+
+ friend class ASTStmtReader;
+};
+
+/// ExpressionTraitExpr - An expression trait intrinsic
+/// Example:
+/// __is_lvalue_expr(std::cout) == true
+/// __is_lvalue_expr(1) == false
+class ExpressionTraitExpr : public Expr {
+ /// ET - The trait. A ExpressionTrait enum in MSVC compat unsigned.
+ unsigned ET : 31;
+ /// The value of the type trait. Unspecified if dependent.
+ bool Value : 1;
+
+ /// Loc - The location of the type trait keyword.
+ SourceLocation Loc;
+
+ /// RParen - The location of the closing paren.
+ SourceLocation RParen;
+
+ Expr* QueriedExpression;
+public:
+ ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et,
+ Expr *queried, bool value,
+ SourceLocation rparen, QualType resultType)
+ : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary,
+ false, // Not type-dependent
+ // Value-dependent if the argument is type-dependent.
+ queried->isTypeDependent(),
+ queried->containsUnexpandedParameterPack()),
+ ET(et), Value(value), Loc(loc), RParen(rparen), QueriedExpression(queried) { }
+
+ explicit ExpressionTraitExpr(EmptyShell Empty)
+ : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false),
+ QueriedExpression() { }
+
+ SourceRange getSourceRange() const { return SourceRange(Loc, RParen);}
+
+ ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
+
+ Expr *getQueriedExpression() const { return QueriedExpression; }
+
+ bool getValue() const { return Value; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ExpressionTraitExprClass;
+ }
+ static bool classof(const ExpressionTraitExpr *) { return true; }
+
+ // Iterators
+ child_range children() { return child_range(); }
+
+ friend class ASTStmtReader;
+};
+
+
/// \brief A reference to an overloaded function set, either an
/// \t UnresolvedLookupExpr or an \t UnresolvedMemberExpr.
class OverloadExpr : public Expr {
@@ -1590,18 +1724,15 @@ class OverloadExpr : public Expr {
/// The common name of these declarations.
DeclarationNameInfo NameInfo;
- /// The scope specifier, if any.
- NestedNameSpecifier *Qualifier;
-
- /// The source range of the scope specifier.
- SourceRange QualifierRange;
+ /// \brief The nested-name-specifier that qualifies the name, if any.
+ NestedNameSpecifierLoc QualifierLoc;
protected:
/// True if the name was a template-id.
bool HasExplicitTemplateArgs;
OverloadExpr(StmtClass K, ASTContext &C,
- NestedNameSpecifier *Qualifier, SourceRange QRange,
+ NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
@@ -1610,7 +1741,7 @@ protected:
OverloadExpr(StmtClass K, EmptyShell Empty)
: Expr(K, Empty), Results(0), NumResults(0),
- Qualifier(0), HasExplicitTemplateArgs(false) { }
+ QualifierLoc(), HasExplicitTemplateArgs(false) { }
void initializeResults(ASTContext &C,
UnresolvedSetIterator Begin,
@@ -1665,23 +1796,21 @@ public:
/// Gets the full name info.
const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
- void setNameInfo(const DeclarationNameInfo &N) { NameInfo = N; }
/// Gets the name looked up.
DeclarationName getName() const { return NameInfo.getName(); }
- void setName(DeclarationName N) { NameInfo.setName(N); }
/// Gets the location of the name.
SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
- void setNameLoc(SourceLocation Loc) { NameInfo.setLoc(Loc); }
/// Fetches the nested-name qualifier, if one was given.
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
- void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
+ NestedNameSpecifier *getQualifier() const {
+ return QualifierLoc.getNestedNameSpecifier();
+ }
- /// Fetches the range of the nested-name qualifier.
- SourceRange getQualifierRange() const { return QualifierRange; }
- void setQualifierRange(SourceRange R) { QualifierRange = R; }
+ /// Fetches the nested-name qualifier with source-location information, if
+ /// one was given.
+ NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
/// \brief Determines whether this expression had an explicit
/// template argument list, e.g. f<int>.
@@ -1727,6 +1856,10 @@ class UnresolvedLookupExpr : public OverloadExpr {
/// call.
bool RequiresADL;
+ /// True if namespace ::std should be considered an associated namespace
+ /// for the purposes of argument-dependent lookup. See C++0x [stmt.ranged]p1.
+ bool StdIsAssociatedNamespace;
+
/// True if these lookup results are overloaded. This is pretty
/// trivially rederivable if we urgently need to kill this field.
bool Overloaded;
@@ -1740,39 +1873,46 @@ class UnresolvedLookupExpr : public OverloadExpr {
UnresolvedLookupExpr(ASTContext &C,
CXXRecordDecl *NamingClass,
- NestedNameSpecifier *Qualifier, SourceRange QRange,
+ NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
bool RequiresADL, bool Overloaded,
const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End)
- : OverloadExpr(UnresolvedLookupExprClass, C, Qualifier, QRange, NameInfo,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End,
+ bool StdIsAssociatedNamespace)
+ : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo,
TemplateArgs, Begin, End),
- RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
+ RequiresADL(RequiresADL),
+ StdIsAssociatedNamespace(StdIsAssociatedNamespace),
+ Overloaded(Overloaded), NamingClass(NamingClass)
{}
UnresolvedLookupExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedLookupExprClass, Empty),
- RequiresADL(false), Overloaded(false), NamingClass(0)
+ RequiresADL(false), StdIsAssociatedNamespace(false), Overloaded(false),
+ NamingClass(0)
{}
+ friend class ASTStmtReader;
+
public:
static UnresolvedLookupExpr *Create(ASTContext &C,
CXXRecordDecl *NamingClass,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
+ NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
bool ADL, bool Overloaded,
UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) {
- return new(C) UnresolvedLookupExpr(C, NamingClass, Qualifier,
- QualifierRange, NameInfo, ADL,
- Overloaded, 0, Begin, End);
+ UnresolvedSetIterator End,
+ bool StdIsAssociatedNamespace = false) {
+ assert((ADL || !StdIsAssociatedNamespace) &&
+ "std considered associated namespace when not performing ADL");
+ return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, NameInfo,
+ ADL, Overloaded, 0, Begin, End,
+ StdIsAssociatedNamespace);
}
static UnresolvedLookupExpr *Create(ASTContext &C,
CXXRecordDecl *NamingClass,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
+ NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
bool ADL,
const TemplateArgumentListInfo &Args,
@@ -1786,17 +1926,18 @@ public:
/// True if this declaration should be extended by
/// argument-dependent lookup.
bool requiresADL() const { return RequiresADL; }
- void setRequiresADL(bool V) { RequiresADL = V; }
+
+ /// True if namespace ::std should be artificially added to the set of
+ /// associated namespaecs for argument-dependent lookup purposes.
+ bool isStdAssociatedNamespace() const { return StdIsAssociatedNamespace; }
/// True if this lookup is overloaded.
bool isOverloaded() const { return Overloaded; }
- void setOverloaded(bool V) { Overloaded = V; }
/// Gets the 'naming class' (in the sense of C++0x
/// [class.access.base]p5) of the lookup. This is the scope
/// that was looked in to find these results.
CXXRecordDecl *getNamingClass() const { return NamingClass; }
- void setNamingClass(CXXRecordDecl *D) { NamingClass = D; }
// Note that, inconsistently with the explicit-template-argument AST
// nodes, users are *forbidden* from calling these methods on objects
@@ -1845,8 +1986,10 @@ public:
SourceRange getSourceRange() const {
SourceRange Range(getNameInfo().getSourceRange());
- if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
- if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
+ if (getQualifierLoc())
+ Range.setBegin(getQualifierLoc().getBeginLoc());
+ if (hasExplicitTemplateArgs())
+ Range.setEnd(getRAngleLoc());
return Range;
}
@@ -2186,16 +2329,13 @@ class CXXDependentScopeMemberExpr : public Expr {
SourceLocation OperatorLoc;
/// \brief The nested-name-specifier that precedes the member name, if any.
- NestedNameSpecifier *Qualifier;
-
- /// \brief The source range covering the nested name specifier.
- SourceRange QualifierRange;
+ NestedNameSpecifierLoc QualifierLoc;
/// \brief In a qualified member access expression such as t->Base::f, this
/// member stores the resolves of name lookup in the context of the member
/// access expression, to be used at instantiation time.
///
- /// FIXME: This member, along with the Qualifier and QualifierRange, could
+ /// FIXME: This member, along with the QualifierLoc, could
/// be stuck into a structure that is optionally allocated at the end of
/// the CXXDependentScopeMemberExpr, to save space in the common case.
NamedDecl *FirstQualifierFoundInScope;
@@ -2208,8 +2348,7 @@ class CXXDependentScopeMemberExpr : public Expr {
CXXDependentScopeMemberExpr(ASTContext &C,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
+ NestedNameSpecifierLoc QualifierLoc,
NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);
@@ -2219,8 +2358,7 @@ public:
Expr *Base, QualType BaseType,
bool IsArrow,
SourceLocation OperatorLoc,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
+ NestedNameSpecifierLoc QualifierLoc,
NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo);
@@ -2228,8 +2366,7 @@ public:
Create(ASTContext &C,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
+ NestedNameSpecifierLoc QualifierLoc,
NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);
@@ -2241,7 +2378,7 @@ public:
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
- bool isImplicitAccess() const { return Base == 0; }
+ bool isImplicitAccess() const;
/// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
@@ -2249,30 +2386,27 @@ public:
assert(!isImplicitAccess());
return cast<Expr>(Base);
}
- void setBase(Expr *E) { Base = E; }
QualType getBaseType() const { return BaseType; }
- void setBaseType(QualType T) { BaseType = T; }
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
- void setArrow(bool A) { IsArrow = A; }
/// \brief Retrieve the location of the '->' or '.' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
- void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
/// \brief Retrieve the nested-name-specifier that qualifies the member
/// name.
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
- void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
-
- /// \brief Retrieve the source range covering the nested-name-specifier
- /// that qualifies the member name.
- SourceRange getQualifierRange() const { return QualifierRange; }
- void setQualifierRange(SourceRange R) { QualifierRange = R; }
+ NestedNameSpecifier *getQualifier() const {
+ return QualifierLoc.getNestedNameSpecifier();
+ }
+ /// \brief Retrieve the nested-name-specifier that qualifies the member
+ /// name, with source location information.
+ NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+
/// \brief Retrieve the first part of the nested-name-specifier that was
/// found in the scope of the member access expression when the member access
/// was initially parsed.
@@ -2287,26 +2421,20 @@ public:
NamedDecl *getFirstQualifierFoundInScope() const {
return FirstQualifierFoundInScope;
}
- void setFirstQualifierFoundInScope(NamedDecl *D) {
- FirstQualifierFoundInScope = D;
- }
/// \brief Retrieve the name of the member that this expression
/// refers to.
const DeclarationNameInfo &getMemberNameInfo() const {
return MemberNameInfo;
}
- void setMemberNameInfo(const DeclarationNameInfo &N) { MemberNameInfo = N; }
/// \brief Retrieve the name of the member that this expression
/// refers to.
DeclarationName getMember() const { return MemberNameInfo.getName(); }
- void setMember(DeclarationName N) { MemberNameInfo.setName(N); }
// \brief Retrieve the location of the name of the member that this
// expression refers to.
SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); }
- void setMemberLoc(SourceLocation L) { MemberNameInfo.setLoc(L); }
/// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
@@ -2376,7 +2504,7 @@ public:
if (!isImplicitAccess())
Range.setBegin(Base->getSourceRange().getBegin());
else if (getQualifier())
- Range.setBegin(getQualifierRange().getBegin());
+ Range.setBegin(getQualifierLoc().getBeginLoc());
else
Range.setBegin(MemberNameInfo.getBeginLoc());
@@ -2438,8 +2566,7 @@ class UnresolvedMemberExpr : public OverloadExpr {
UnresolvedMemberExpr(ASTContext &C, bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
+ NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
@@ -2448,13 +2575,14 @@ class UnresolvedMemberExpr : public OverloadExpr {
: OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
HasUnresolvedUsing(false), Base(0) { }
+ friend class ASTStmtReader;
+
public:
static UnresolvedMemberExpr *
Create(ASTContext &C, bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
+ NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
@@ -2466,7 +2594,7 @@ public:
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
- bool isImplicitAccess() const { return Base == 0; }
+ bool isImplicitAccess() const;
/// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
@@ -2478,24 +2606,19 @@ public:
assert(!isImplicitAccess());
return cast<Expr>(Base);
}
- void setBase(Expr *E) { Base = E; }
QualType getBaseType() const { return BaseType; }
- void setBaseType(QualType T) { BaseType = T; }
/// \brief Determine whether the lookup results contain an unresolved using
/// declaration.
bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
- void setHasUnresolvedUsing(bool V) { HasUnresolvedUsing = V; }
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
- void setArrow(bool A) { IsArrow = A; }
/// \brief Retrieve the location of the '->' or '.' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
- void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
/// \brief Retrieves the naming class of this lookup.
CXXRecordDecl *getNamingClass() const;
@@ -2503,17 +2626,14 @@ public:
/// \brief Retrieve the full name info for the member that this expression
/// refers to.
const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
- void setMemberNameInfo(const DeclarationNameInfo &N) { setNameInfo(N); }
/// \brief Retrieve the name of the member that this expression
/// refers to.
DeclarationName getMemberName() const { return getName(); }
- void setMemberName(DeclarationName N) { setName(N); }
// \brief Retrieve the location of the name of the member that this
// expression refers to.
SourceLocation getMemberLoc() const { return getNameLoc(); }
- void setMemberLoc(SourceLocation L) { setNameLoc(L); }
/// \brief Retrieve the explicit template argument list that followed the
/// member template name.
@@ -2570,8 +2690,8 @@ public:
SourceRange Range = getMemberNameInfo().getSourceRange();
if (!isImplicitAccess())
Range.setBegin(Base->getSourceRange().getBegin());
- else if (getQualifier())
- Range.setBegin(getQualifierRange().getBegin());
+ else if (getQualifierLoc())
+ Range.setBegin(getQualifierLoc().getBeginLoc());
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index 285efb757bbb..8163923d62d1 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -337,6 +337,39 @@ public:
QualType getSuperReceiverType() const {
return QualType(Receiver.get<const Type*>(), 0);
}
+ QualType getGetterResultType() const {
+ QualType ResultType;
+ if (isExplicitProperty()) {
+ const ObjCPropertyDecl *PDecl = getExplicitProperty();
+ if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
+ ResultType = Getter->getResultType();
+ else
+ ResultType = getType();
+ } else {
+ const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
+ ResultType = Getter->getResultType(); // with reference!
+ }
+ return ResultType;
+ }
+
+ QualType getSetterArgType() const {
+ QualType ArgType;
+ if (isImplicitProperty()) {
+ const ObjCMethodDecl *Setter = getImplicitPropertySetter();
+ ObjCMethodDecl::param_iterator P = Setter->param_begin();
+ ArgType = (*P)->getType();
+ } else {
+ if (ObjCPropertyDecl *PDecl = getExplicitProperty())
+ if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
+ ObjCMethodDecl::param_iterator P = Setter->param_begin();
+ ArgType = (*P)->getType();
+ }
+ if (ArgType.isNull())
+ ArgType = getType();
+ }
+ return ArgType;
+ }
+
ObjCInterfaceDecl *getClassReceiver() const {
return Receiver.get<ObjCInterfaceDecl*>();
}
@@ -741,6 +774,11 @@ public:
SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
}
+ ObjCMethodFamily getMethodFamily() const {
+ if (HasMethod) return getMethodDecl()->getMethodFamily();
+ return getSelector().getMethodFamily();
+ }
+
/// \brief Return the number of actual arguments in this message,
/// not counting the receiver.
unsigned getNumArgs() const { return NumArgs; }
@@ -808,7 +846,7 @@ public:
};
/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
-/// (similiar in spirit to MemberExpr).
+/// (similar in spirit to MemberExpr).
class ObjCIsaExpr : public Expr {
/// Base - the expression for the base object pointer.
Stmt *Base;
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 7b23766b0714..6db233641220 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file defines the ExternalASTSource interface, which enables
-// construction of AST nodes from some external source.x
+// construction of AST nodes from some external source.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
@@ -16,7 +16,6 @@
#include "clang/AST/DeclBase.h"
#include <cassert>
-#include <vector>
namespace llvm {
template <class T> class SmallVectorImpl;
@@ -26,9 +25,6 @@ namespace clang {
class ASTConsumer;
class CXXBaseSpecifier;
-class Decl;
-class DeclContext;
-class DeclContextLookupResult;
class DeclarationName;
class ExternalSemaSource; // layering violation required for downcasting
class NamedDecl;
@@ -74,17 +70,23 @@ public:
///
/// This method only needs to be implemented if the AST source ever
/// passes back decl sets as VisibleDeclaration objects.
- virtual Decl *GetExternalDecl(uint32_t ID) = 0;
+ ///
+ /// The default implementation of this method is a no-op.
+ virtual Decl *GetExternalDecl(uint32_t ID);
/// \brief Resolve a selector ID into a selector.
///
/// This operation only needs to be implemented if the AST source
/// returns non-zero for GetNumKnownSelectors().
- virtual Selector GetExternalSelector(uint32_t ID) = 0;
+ ///
+ /// The default implementation of this method is a no-op.
+ virtual Selector GetExternalSelector(uint32_t ID);
/// \brief Returns the number of selectors known to the external AST
/// source.
- virtual uint32_t GetNumExternalSelectors() = 0;
+ ///
+ /// The default implementation of this method is a no-op.
+ virtual uint32_t GetNumExternalSelectors();
/// \brief Resolve the offset of a statement in the decl stream into
/// a statement.
@@ -92,21 +94,26 @@ public:
/// This operation is meant to be used via a LazyOffsetPtr. It only
/// needs to be implemented if the AST source uses methods like
/// FunctionDecl::setLazyBody when building decls.
- virtual Stmt *GetExternalDeclStmt(uint64_t Offset) = 0;
+ ///
+ /// The default implementation of this method is a no-op.
+ virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
/// \brief Resolve the offset of a set of C++ base specifiers in the decl
/// stream into an array of specifiers.
- virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) = 0;
-
+ ///
+ /// The default implementation of this method is a no-op.
+ virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
+
/// \brief Finds all declarations with the given name in the
/// given context.
///
/// Generally the final step of this method is either to call
/// SetExternalVisibleDeclsForName or to recursively call lookup on
/// the DeclContext after calling SetExternalVisibleDecls.
+ ///
+ /// The default implementation of this method is a no-op.
virtual DeclContextLookupResult
- FindExternalVisibleDeclsByName(const DeclContext *DC,
- DeclarationName Name) = 0;
+ FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
/// \brief Deserialize all the visible declarations from external storage.
///
@@ -114,7 +121,9 @@ public:
/// may not have a complete name lookup table. This function deserializes
/// the rest of visible declarations from the external storage and completes
/// the name lookup table of the DeclContext.
- virtual void MaterializeVisibleDecls(const DeclContext *DC) = 0;
+ ///
+ /// The default implementation of this method is a no-op.
+ virtual void MaterializeVisibleDecls(const DeclContext *DC);
/// \brief Finds all declarations lexically contained within the given
/// DeclContext, after applying an optional filter predicate.
@@ -124,9 +133,11 @@ public:
/// are returned.
///
/// \return true if an error occurred
+ ///
+ /// The default implementation of this method is a no-op.
virtual bool FindExternalLexicalDecls(const DeclContext *DC,
bool (*isKindWeWant)(Decl::Kind),
- llvm::SmallVectorImpl<Decl*> &Result) = 0;
+ llvm::SmallVectorImpl<Decl*> &Result);
/// \brief Finds all declarations lexically contained within the given
/// DeclContext.
@@ -154,7 +165,7 @@ public:
/// set on the ObjCInterfaceDecl via the function
/// \c ObjCInterfaceDecl::setExternallyCompleted().
virtual void CompleteType(ObjCInterfaceDecl *Class) { }
-
+
/// \brief Notify ExternalASTSource that we started deserialization of
/// a decl or type so until FinishedDeserializing is called there may be
/// decls that are initializing. Must be paired with FinishedDeserializing.
@@ -179,6 +190,28 @@ public:
///
/// The default implementation of this method is a no-op.
virtual void PrintStats();
+
+ //===--------------------------------------------------------------------===//
+ // Queries for performance analysis.
+ //===--------------------------------------------------------------------===//
+
+ struct MemoryBufferSizes {
+ size_t malloc_bytes;
+ size_t mmap_bytes;
+
+ MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
+ : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
+ };
+
+ /// Return the amount of memory used by memory buffers, breaking down
+ /// by heap-backed versus mmap'ed memory.
+ MemoryBufferSizes getMemoryBufferSizes() const {
+ MemoryBufferSizes sizes(0, 0);
+ getMemoryBufferSizes(sizes);
+ return sizes;
+ }
+
+ virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const = 0;
protected:
static DeclContextLookupResult
@@ -270,7 +303,7 @@ typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
&ExternalASTSource::GetExternalCXXBaseSpecifiers>
LazyCXXBaseSpecifiersPtr;
-
+
} // end namespace clang
#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index 024bf402894b..c21c76b006ff 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -312,6 +312,146 @@ public:
}
};
+/// \brief Class that aids in the construction of nested-name-specifiers along
+/// with source-location information for all of the components of the
+/// nested-name-specifier.
+class NestedNameSpecifierLocBuilder {
+ /// \brief The current representation of the nested-name-specifier we're
+ /// building.
+ NestedNameSpecifier *Representation;
+
+ /// \brief Buffer used to store source-location information for the
+ /// nested-name-specifier.
+ ///
+ /// Note that we explicitly manage the buffer (rather than using a
+ /// SmallVector) because \c Declarator expects it to be possible to memcpy()
+ /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
+ char *Buffer;
+
+ /// \brief The size of the buffer used to store source-location information
+ /// for the nested-name-specifier.
+ unsigned BufferSize;
+
+ /// \brief The capacity of the buffer used to store source-location
+ /// information for the nested-name-specifier.
+ unsigned BufferCapacity;
+
+public:
+ NestedNameSpecifierLocBuilder();
+
+ NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
+
+ NestedNameSpecifierLocBuilder &
+ operator=(const NestedNameSpecifierLocBuilder &Other);
+
+ ~NestedNameSpecifierLocBuilder();
+
+ /// \brief Retrieve the representation of the nested-name-specifier.
+ NestedNameSpecifier *getRepresentation() const { return Representation; }
+
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'type::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param TemplateKWLoc The location of the 'template' keyword, if present.
+ ///
+ /// \param TL The TypeLoc that describes the type preceding the '::'.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
+ SourceLocation ColonColonLoc);
+
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'identifier::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param Identifier The identifier.
+ ///
+ /// \param IdentifierLoc The location of the identifier.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, IdentifierInfo *Identifier,
+ SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
+
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'namespace::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param Namespace The namespace.
+ ///
+ /// \param NamespaceLoc The location of the namespace name.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, NamespaceDecl *Namespace,
+ SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
+
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'namespace-alias::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param Alias The namespace alias.
+ ///
+ /// \param AliasLoc The location of the namespace alias
+ /// name.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
+ SourceLocation AliasLoc, SourceLocation ColonColonLoc);
+
+ /// \brief Turn this (empty) nested-name-specifier into the global
+ /// nested-name-specifier '::'.
+ void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
+
+ /// \brief Make a new nested-name-specifier from incomplete source-location
+ /// information.
+ ///
+ /// This routine should be used very, very rarely, in cases where we
+ /// need to synthesize a nested-name-specifier. Most code should instead use
+ /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
+ void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
+ SourceRange R);
+
+ /// \brief Adopt an existing nested-name-specifier (with source-range
+ /// information).
+ void Adopt(NestedNameSpecifierLoc Other);
+
+ /// \brief Retrieve the source range covered by this nested-name-specifier.
+ SourceRange getSourceRange() const {
+ return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
+ }
+
+ /// \brief Retrieve a nested-name-specifier with location information,
+ /// copied into the given AST context.
+ ///
+ /// \param Context The context into which this nested-name-specifier will be
+ /// copied.
+ NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
+
+ /// \brief Clear out this builder, and prepare it to build another
+ /// nested-name-specifier with source-location information.
+ void Clear() {
+ Representation = 0;
+ BufferSize = 0;
+ }
+
+ /// \brief Retrieve the underlying buffer.
+ ///
+ /// \returns A pair containing a pointer to the buffer of source-location
+ /// data and the size of the source-location data that resides in that
+ /// buffer.
+ std::pair<char *, unsigned> getBuffer() const {
+ return std::make_pair(Buffer, BufferSize);
+ }
+};
+
/// Insertion operator for diagnostics. This allows sending NestedNameSpecifiers
/// into a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index a59c302ffc1e..cf5fadbd1850 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -38,7 +38,8 @@ struct PrintingPolicy {
/// \brief Create a default printing policy for C.
PrintingPolicy(const LangOptions &LO)
: Indentation(2), LangOpts(LO), SuppressSpecifiers(false),
- SuppressTag(false), SuppressScope(false),
+ SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false),
+ SuppressInitializers(false),
Dump(false), ConstantArraySizeAsWritten(false),
AnonymousTagLocations(true) { }
@@ -64,6 +65,16 @@ struct PrintingPolicy {
/// "const int" type specifier and instead only print the "*y".
bool SuppressSpecifiers : 1;
+ /// \brief Whether type printing should skip printing the tag keyword.
+ ///
+ /// This is used when printing the inner type of elaborated types,
+ /// (as the tag keyword is part of the elaborated type):
+ ///
+ /// \code
+ /// struct Geometry::Point;
+ /// \endcode
+ bool SuppressTagKeyword : 1;
+
/// \brief Whether type printing should skip printing the actual tag type.
///
/// This is used when the caller needs to print a tag definition in front
@@ -77,6 +88,19 @@ struct PrintingPolicy {
/// \brief Suppresses printing of scope specifiers.
bool SuppressScope : 1;
+ /// \brief Suppress printing of variable initializers.
+ ///
+ /// This flag is used when printing the loop variable in a for-range
+ /// statement. For example, given:
+ ///
+ /// \code
+ /// for (auto x : coll)
+ /// \endcode
+ ///
+ /// SuppressInitializers will be true when printing "auto x", so that the
+ /// internal initializer constructed for x will not be printed.
+ bool SuppressInitializers : 1;
+
/// \brief True when we are "dumping" rather than "pretty-printing",
/// where dumping involves printing the internal details of the AST
/// and pretty-printing involves printing something similar to
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index e85b6dcd279a..930d19373cdc 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -600,12 +600,15 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
// FIXME: how can TSI ever be NULL?
if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
- else
- return true;
+ else
+ return getDerived().TraverseType(Arg.getAsType());
}
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
+ if (ArgLoc.getTemplateQualifierLoc())
+ TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
+ ArgLoc.getTemplateQualifierLoc()));
return getDerived().TraverseTemplateName(
Arg.getAsTemplateOrTemplatePattern());
@@ -933,7 +936,11 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
const FunctionProtoType *T = TL.getTypePtr();
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseDecl(TL.getArg(I)));
+ if (TL.getArg(I)) {
+ TRY_TO(TraverseDecl(TL.getArg(I)));
+ } else if (I < T->getNumArgs()) {
+ TRY_TO(TraverseType(T->getArgType(I)));
+ }
}
for (FunctionProtoType::exception_iterator E = T->exception_begin(),
@@ -987,21 +994,22 @@ DEF_TRAVERSE_TYPELOC(AttributedType, {
TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
})
-// FIXME: use the sourceloc on qualifier?
DEF_TRAVERSE_TYPELOC(ElaboratedType, {
- if (TL.getTypePtr()->getQualifier()) {
- TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
}
TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
})
-// FIXME: use the sourceloc on qualifier?
DEF_TRAVERSE_TYPELOC(DependentNameType, {
- TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
})
DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ }
+
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
}
@@ -1041,7 +1049,9 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
for (DeclContext::decl_iterator Child = DC->decls_begin(),
ChildEnd = DC->decls_end();
Child != ChildEnd; ++Child) {
- TRY_TO(TraverseDecl(*Child));
+ // BlockDecls are traversed through BlockExprs.
+ if (!isa<BlockDecl>(*Child))
+ TRY_TO(TraverseDecl(*Child));
}
return true;
@@ -1060,10 +1070,12 @@ bool RecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) { \
DEF_TRAVERSE_DECL(AccessSpecDecl, { })
DEF_TRAVERSE_DECL(BlockDecl, {
- // We don't traverse nodes in param_begin()/param_end(), as they
- // appear in decls_begin()/decls_end() and thus are handled by the
- // DEF_TRAVERSE_DECL macro already.
+ TRY_TO(TraverseTypeLoc(D->getSignatureAsWritten()->getTypeLoc()));
TRY_TO(TraverseStmt(D->getBody()));
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
})
DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
@@ -1164,9 +1176,17 @@ DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
})
DEF_TRAVERSE_DECL(ObjCMethodDecl, {
- // We don't traverse nodes in param_begin()/param_end(), as they
- // appear in decls_begin()/decls_end() and thus are handled.
- TRY_TO(TraverseStmt(D->getBody()));
+ if (D->getResultTypeSourceInfo()) {
+ TRY_TO(TraverseTypeLoc(D->getResultTypeSourceInfo()->getTypeLoc()));
+ }
+ for (ObjCMethodDecl::param_iterator
+ I = D->param_begin(), E = D->param_end(); I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ if (D->isThisDeclarationADefinition()) {
+ TRY_TO(TraverseStmt(D->getBody()));
+ }
+ return true;
})
DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
@@ -1341,6 +1361,13 @@ DEF_TRAVERSE_DECL(TypedefDecl, {
// source.
})
+DEF_TRAVERSE_DECL(TypeAliasDecl, {
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the type alias, not something that was written in the
+ // source.
+ })
+
DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
// A dependent using declaration which was marked with 'typename'.
// template<class T> class A : public B<T> { using typename B<T>::foo; };
@@ -1354,7 +1381,7 @@ DEF_TRAVERSE_DECL(EnumDecl, {
if (D->getTypeForDecl())
TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
- TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
// The enumerators are already traversed by
// decls_begin()/decls_end().
})
@@ -1367,7 +1394,7 @@ bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(
// We shouldn't traverse D->getTypeForDecl(); it's a result of
// declaring the type, not something that was written in the source.
- TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
return true;
}
@@ -1464,9 +1491,11 @@ DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
- TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
if (D->getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ else
+ TRY_TO(TraverseType(D->getType()));
return true;
}
@@ -1492,7 +1521,7 @@ DEF_TRAVERSE_DECL(ObjCIvarDecl, {
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
- TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
// If we're an explicit template specialization, iterate over the
// template args that were explicitly specified. If we were doing
@@ -1678,13 +1707,14 @@ DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
+DEF_TRAVERSE_STMT(CXXForRangeStmt, { })
DEF_TRAVERSE_STMT(ReturnStmt, { })
DEF_TRAVERSE_STMT(SwitchStmt, { })
DEF_TRAVERSE_STMT(WhileStmt, { })
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (S->hasExplicitTemplateArgs()) {
TRY_TO(TraverseTemplateArgumentLocsHelper(
S->getTemplateArgs(), S->getNumTemplateArgs()));
@@ -1692,7 +1722,7 @@ DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
})
DEF_TRAVERSE_STMT(DeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
TRY_TO(TraverseTemplateArgumentLocsHelper(
S->getTemplateArgs(), S->getNumTemplateArgs()));
})
@@ -1707,10 +1737,9 @@ DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
})
DEF_TRAVERSE_STMT(MemberExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
TRY_TO(TraverseTemplateArgumentLocsHelper(
S->getTemplateArgs(), S->getNumTemplateArgs()));
- // FIXME: Should we be recursing on the qualifier?
- TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
})
DEF_TRAVERSE_STMT(ImplicitCastExpr, {
@@ -1759,6 +1788,22 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
return true;
}
+// GenericSelectionExpr is a special case because the types and expressions
+// are interleaved. We also need to watch out for null types (default
+// generic associations).
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::
+TraverseGenericSelectionExpr(GenericSelectionExpr *S) {
+ TRY_TO(WalkUpFromGenericSelectionExpr(S));
+ TRY_TO(TraverseStmt(S->getControllingExpr()));
+ for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
+ if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
+ TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
+ TRY_TO(TraverseStmt(S->getAssocExpr(i)));
+ }
+ return true;
+}
+
DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
// This is called for code like 'return T()' where T is a built-in
// (i.e. non-class) type.
@@ -1778,7 +1823,7 @@ DEF_TRAVERSE_STMT(OffsetOfExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(SizeOfAlignOfExpr, {
+DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
// The child-iterator will pick up the arg if it's an expression,
// but not if it's a type.
if (S->isArgumentType())
@@ -1808,6 +1853,14 @@ DEF_TRAVERSE_STMT(BinaryTypeTraitExpr, {
TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
})
+DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
+ TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_STMT(ExpressionTraitExpr, {
+ TRY_TO(TraverseStmt(S->getQueriedExpression()));
+ })
+
DEF_TRAVERSE_STMT(VAArgExpr, {
// The child-iterator will pick up the expression argument.
TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
@@ -1834,7 +1887,10 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, { })
DEF_TRAVERSE_STMT(AddrLabelExpr, { })
DEF_TRAVERSE_STMT(ArraySubscriptExpr, { })
DEF_TRAVERSE_STMT(BlockDeclRefExpr, { })
-DEF_TRAVERSE_STMT(BlockExpr, { })
+DEF_TRAVERSE_STMT(BlockExpr, {
+ TRY_TO(TraverseDecl(S->getBlockDecl()));
+ return true; // no child statements to loop through.
+})
DEF_TRAVERSE_STMT(ChooseExpr, { })
DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
@@ -1869,7 +1925,7 @@ DEF_TRAVERSE_STMT(PredefinedExpr, { })
DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
DEF_TRAVERSE_STMT(StmtExpr, { })
DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
- TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (S->hasExplicitTemplateArgs()) {
TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
S->getNumTemplateArgs()));
@@ -1877,13 +1933,17 @@ DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
})
DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (S->hasExplicitTemplateArgs()) {
TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
S->getNumTemplateArgs()));
}
})
+DEF_TRAVERSE_STMT(SEHTryStmt, {})
+DEF_TRAVERSE_STMT(SEHExceptStmt, {})
+DEF_TRAVERSE_STMT(SEHFinallyStmt,{})
+
DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
DEF_TRAVERSE_STMT(OpaqueValueExpr, { })
DEF_TRAVERSE_STMT(CUDAKernelCallExpr, { })
@@ -1921,7 +1981,7 @@ DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
// Candidates:
//
// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
-// http://clang.llvm.org/doxygen/classclang_1_1SizeOfAlignOfExpr.html
+// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
// Every class that has getQualifier.
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index d1f7d667f33d..695fb0403ead 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -158,6 +158,16 @@ protected:
};
enum { NumExprBits = 15 };
+ class DeclRefExprBitfields {
+ friend class DeclRefExpr;
+ friend class ASTStmtReader; // deserialization
+ unsigned : NumExprBits;
+
+ unsigned HasQualifier : 1;
+ unsigned HasExplicitTemplateArgs : 1;
+ unsigned HasFoundDecl : 1;
+ };
+
class CastExprBitfields {
friend class CastExpr;
unsigned : NumExprBits;
@@ -180,6 +190,7 @@ protected:
StmtBitfields StmtBits;
CompoundStmtBitfields CompoundStmtBits;
ExprBitfields ExprBits;
+ DeclRefExprBitfields DeclRefExprBits;
CastExprBitfields CastExprBits;
CallExprBitfields CallExprBits;
};
@@ -383,14 +394,15 @@ public:
class NullStmt : public Stmt {
SourceLocation SemiLoc;
- /// \brief Whether the null statement was preceded by an empty macro, e.g:
+ /// \brief If the null statement was preceded by an empty macro this is
+ /// its instantiation source location, e.g:
/// @code
/// #define CALL(x)
/// CALL(0);
/// @endcode
- bool LeadingEmptyMacro;
+ SourceLocation LeadingEmptyMacro;
public:
- NullStmt(SourceLocation L, bool LeadingEmptyMacro = false)
+ NullStmt(SourceLocation L, SourceLocation LeadingEmptyMacro =SourceLocation())
: Stmt(NullStmtClass), SemiLoc(L), LeadingEmptyMacro(LeadingEmptyMacro) {}
/// \brief Build an empty null statement.
@@ -399,7 +411,8 @@ public:
SourceLocation getSemiLoc() const { return SemiLoc; }
void setSemiLoc(SourceLocation L) { SemiLoc = L; }
- bool hasLeadingEmptyMacro() const { return LeadingEmptyMacro; }
+ bool hasLeadingEmptyMacro() const { return LeadingEmptyMacro.isValid(); }
+ SourceLocation getLeadingEmptyMacroLoc() const { return LeadingEmptyMacro; }
SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
@@ -424,6 +437,8 @@ public:
SourceLocation LB, SourceLocation RB)
: Stmt(CompoundStmtClass), LBracLoc(LB), RBracLoc(RB) {
CompoundStmtBits.NumStmts = NumStmts;
+ assert(CompoundStmtBits.NumStmts == NumStmts &&
+ "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
if (NumStmts == 0) {
Body = 0;
@@ -516,6 +531,9 @@ public:
void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
Stmt *getSubStmt();
+ const Stmt *getSubStmt() const {
+ return const_cast<SwitchCase*>(this)->getSubStmt();
+ }
SourceRange getSourceRange() const { return SourceRange(); }
@@ -527,7 +545,7 @@ public:
};
class CaseStmt : public SwitchCase {
- enum { SUBSTMT, LHS, RHS, END_EXPR };
+ enum { LHS, RHS, SUBSTMT, END_EXPR };
Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
// GNU "case 1 ... 4" extension
SourceLocation CaseLoc;
@@ -688,6 +706,12 @@ public:
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
+ /// If this IfStmt has a condition variable, return the faux DeclStmt
+ /// associated with the creation of that condition variable.
+ const DeclStmt *getConditionVariableDeclStmt() const {
+ return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+ }
+
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
const Stmt *getThen() const { return SubExprs[THEN]; }
@@ -754,6 +778,12 @@ public:
/// \endcode
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
+
+ /// If this SwitchStmt has a condition variable, return the faux DeclStmt
+ /// associated with the creation of that condition variable.
+ const DeclStmt *getConditionVariableDeclStmt() const {
+ return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+ }
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
const Stmt *getBody() const { return SubExprs[BODY]; }
@@ -835,6 +865,12 @@ public:
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
+ /// If this WhileStmt has a condition variable, return the faux DeclStmt
+ /// associated with the creation of that condition variable.
+ const DeclStmt *getConditionVariableDeclStmt() const {
+ return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+ }
+
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
@@ -939,6 +975,12 @@ public:
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
+ /// If this ForStmt has a condition variable, return the faux DeclStmt
+ /// associated with the creation of that condition variable.
+ const DeclStmt *getConditionVariableDeclStmt() const {
+ return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
+ }
+
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
Stmt *getBody() { return SubExprs[BODY]; }
@@ -1406,6 +1448,122 @@ public:
}
};
+class SEHExceptStmt : public Stmt {
+ SourceLocation Loc;
+ Stmt *Children[2];
+
+ enum { FILTER_EXPR, BLOCK };
+
+ SEHExceptStmt(SourceLocation Loc,
+ Expr *FilterExpr,
+ Stmt *Block);
+
+public:
+ static SEHExceptStmt* Create(ASTContext &C,
+ SourceLocation ExceptLoc,
+ Expr *FilterExpr,
+ Stmt *Block);
+ SourceRange getSourceRange() const {
+ return SourceRange(getExceptLoc(), getEndLoc());
+ }
+
+ SourceLocation getExceptLoc() const { return Loc; }
+ SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); }
+
+ Expr *getFilterExpr() const { return reinterpret_cast<Expr*>(Children[FILTER_EXPR]); }
+ CompoundStmt *getBlock() const { return llvm::cast<CompoundStmt>(Children[BLOCK]); }
+
+ child_range children() {
+ return child_range(Children,Children+2);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == SEHExceptStmtClass;
+ }
+
+ static bool classof(SEHExceptStmt *) { return true; }
+
+};
+
+class SEHFinallyStmt : public Stmt {
+ SourceLocation Loc;
+ Stmt *Block;
+
+ SEHFinallyStmt(SourceLocation Loc,
+ Stmt *Block);
+
+public:
+ static SEHFinallyStmt* Create(ASTContext &C,
+ SourceLocation FinallyLoc,
+ Stmt *Block);
+
+ SourceRange getSourceRange() const {
+ return SourceRange(getFinallyLoc(), getEndLoc());
+ }
+
+ SourceLocation getFinallyLoc() const { return Loc; }
+ SourceLocation getEndLoc() const { return Block->getLocEnd(); }
+
+ CompoundStmt *getBlock() const { return llvm::cast<CompoundStmt>(Block); }
+
+ child_range children() {
+ return child_range(&Block,&Block+1);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == SEHFinallyStmtClass;
+ }
+
+ static bool classof(SEHFinallyStmt *) { return true; }
+
+};
+
+class SEHTryStmt : public Stmt {
+ bool IsCXXTry;
+ SourceLocation TryLoc;
+ Stmt *Children[2];
+
+ enum { TRY = 0, HANDLER = 1 };
+
+ SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
+ SourceLocation TryLoc,
+ Stmt *TryBlock,
+ Stmt *Handler);
+
+public:
+ static SEHTryStmt* Create(ASTContext &C,
+ bool isCXXTry,
+ SourceLocation TryLoc,
+ Stmt *TryBlock,
+ Stmt *Handler);
+
+ SourceRange getSourceRange() const {
+ return SourceRange(getTryLoc(), getEndLoc());
+ }
+
+ SourceLocation getTryLoc() const { return TryLoc; }
+ SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); }
+
+ bool getIsCXXTry() const { return IsCXXTry; }
+ CompoundStmt* getTryBlock() const { return llvm::cast<CompoundStmt>(Children[TRY]); }
+ Stmt *getHandler() const { return Children[HANDLER]; }
+
+ /// Returns 0 if not defined
+ SEHExceptStmt *getExceptHandler() const;
+ SEHFinallyStmt *getFinallyHandler() const;
+
+ child_range children() {
+ return child_range(Children,Children+2);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == SEHTryStmtClass;
+ }
+
+ static bool classof(SEHTryStmt *) { return true; }
+
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index f08815fd562d..42dcf2bb7b79 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -119,6 +119,88 @@ public:
friend class ASTStmtReader;
};
+/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
+/// statement, represented as 'for (range-declarator : range-expression)'.
+///
+/// This is stored in a partially-desugared form to allow full semantic
+/// analysis of the constituent components. The original syntactic components
+/// can be extracted using getLoopVariable and getRangeInit.
+class CXXForRangeStmt : public Stmt {
+ enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END };
+ // SubExprs[RANGE] is an expression or declstmt.
+ // SubExprs[COND] and SubExprs[INC] are expressions.
+ Stmt *SubExprs[END];
+ SourceLocation ForLoc;
+ SourceLocation ColonLoc;
+ SourceLocation RParenLoc;
+public:
+ CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd,
+ Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
+ SourceLocation FL, SourceLocation CL, SourceLocation RPL);
+ CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
+
+
+ VarDecl *getLoopVariable();
+ Expr *getRangeInit();
+
+ const VarDecl *getLoopVariable() const;
+ const Expr *getRangeInit() const;
+
+
+ DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
+ DeclStmt *getBeginEndStmt() { return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); }
+ Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
+ Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
+ DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
+ Stmt *getBody() { return SubExprs[BODY]; }
+
+ const DeclStmt *getRangeStmt() const {
+ return cast<DeclStmt>(SubExprs[RANGE]);
+ }
+ const DeclStmt *getBeginEndStmt() const {
+ return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
+ }
+ const Expr *getCond() const {
+ return cast_or_null<Expr>(SubExprs[COND]);
+ }
+ const Expr *getInc() const {
+ return cast_or_null<Expr>(SubExprs[INC]);
+ }
+ const DeclStmt *getLoopVarStmt() const {
+ return cast<DeclStmt>(SubExprs[LOOPVAR]);
+ }
+ const Stmt *getBody() const { return SubExprs[BODY]; }
+
+ void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
+ void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
+ void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; }
+ void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
+ void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
+ void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
+ void setBody(Stmt *S) { SubExprs[BODY] = S; }
+
+
+ SourceLocation getForLoc() const { return ForLoc; }
+ void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
+ SourceLocation getColonLoc() const { return ColonLoc; }
+ void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXForRangeStmtClass;
+ }
+ static bool classof(const CXXForRangeStmt *) { return true; }
+
+ // Iterators
+ child_range children() {
+ return child_range(&SubExprs[0], &SubExprs[END]);
+ }
+};
+
} // end namespace clang
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index 851c001adc54..05b50db7def7 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -18,6 +18,7 @@
#include <cassert>
#include <cstddef>
#include <iterator>
+#include <utility>
namespace clang {
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index a4e074e083f6..821b4fcbb168 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -362,7 +362,10 @@ private:
Expr *Expression;
TypeSourceInfo *Declarator;
struct {
- unsigned QualifierRange[2];
+ // FIXME: We'd like to just use the qualifier in the TemplateName,
+ // but template arguments get canonicalized too quickly.
+ NestedNameSpecifier *Qualifier;
+ void *QualifierLocData;
unsigned TemplateNameLoc;
unsigned EllipsisLoc;
} Template;
@@ -375,12 +378,12 @@ public:
TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
- TemplateArgumentLocInfo(SourceRange QualifierRange,
+ TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc)
{
- Template.QualifierRange[0] = QualifierRange.getBegin().getRawEncoding();
- Template.QualifierRange[1] = QualifierRange.getEnd().getRawEncoding();
+ Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
+ Template.QualifierLocData = QualifierLoc.getOpaqueData();
Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
}
@@ -393,10 +396,9 @@ public:
return Expression;
}
- SourceRange getTemplateQualifierRange() const {
- return SourceRange(
- SourceLocation::getFromRawEncoding(Template.QualifierRange[0]),
- SourceLocation::getFromRawEncoding(Template.QualifierRange[1]));
+ NestedNameSpecifierLoc getTemplateQualifierLoc() const {
+ return NestedNameSpecifierLoc(Template.Qualifier,
+ Template.QualifierLocData);
}
SourceLocation getTemplateNameLoc() const {
@@ -433,11 +435,10 @@ public:
}
TemplateArgumentLoc(const TemplateArgument &Argument,
- SourceRange QualifierRange,
+ NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc = SourceLocation())
- : Argument(Argument),
- LocInfo(QualifierRange, TemplateNameLoc, EllipsisLoc) {
+ : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
assert(Argument.getKind() == TemplateArgument::Template ||
Argument.getKind() == TemplateArgument::TemplateExpansion);
}
@@ -477,10 +478,10 @@ public:
return LocInfo.getAsExpr();
}
- SourceRange getTemplateQualifierRange() const {
+ NestedNameSpecifierLoc getTemplateQualifierLoc() const {
assert(Argument.getKind() == TemplateArgument::Template ||
Argument.getKind() == TemplateArgument::TemplateExpansion);
- return LocInfo.getTemplateQualifierRange();
+ return LocInfo.getTemplateQualifierLoc();
}
SourceLocation getTemplateNameLoc() const {
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 9b177cceed96..975a66fefa89 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_TYPE_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Linkage.h"
#include "clang/Basic/PartialDiagnostic.h"
@@ -72,7 +73,7 @@ namespace llvm {
namespace clang {
class ASTContext;
- class TypedefDecl;
+ class TypedefNameDecl;
class TemplateDecl;
class TemplateTypeParmDecl;
class NonTypeTemplateParmDecl;
@@ -212,6 +213,11 @@ public:
assert(type);
setObjCGCAttr(type);
}
+ Qualifiers withoutObjCGCAttr() const {
+ Qualifiers qs = *this;
+ qs.removeObjCGCAttr();
+ return qs;
+ }
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
@@ -293,8 +299,10 @@ public:
(((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
}
- 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;
+
bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
@@ -354,7 +362,9 @@ enum CallingConv {
CC_X86StdCall, // __attribute__((stdcall))
CC_X86FastCall, // __attribute__((fastcall))
CC_X86ThisCall, // __attribute__((thiscall))
- CC_X86Pascal // __attribute__((pascal))
+ CC_X86Pascal, // __attribute__((pascal))
+ CC_AAPCS, // __attribute__((pcs("aapcs")))
+ CC_AAPCS_VFP // __attribute__((pcs("aapcs-vfp")))
};
typedef std::pair<const Type*, Qualifiers> SplitQualType;
@@ -598,8 +608,14 @@ public:
/// ASTContext::getUnqualifiedArrayType.
inline SplitQualType getSplitUnqualifiedType() const;
+ /// \brief Determine whether this type is more qualified than the other
+ /// given type, requiring exact equality for non-CVR qualifiers.
bool isMoreQualifiedThan(QualType Other) const;
+
+ /// \brief Determine whether this type is at least as qualified as the other
+ /// given type, requiring exact equality for non-CVR qualifiers.
bool isAtLeastAsQualifiedAs(QualType Other) const;
+
QualType getNonReferenceType() const;
/// \brief Determine the type of a (typically non-lvalue) expression with the
@@ -1163,6 +1179,20 @@ public:
/// (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;
+
+ /// \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.
@@ -1178,6 +1208,9 @@ public:
/// BuiltinTypes.
bool isPlaceholderType() const;
+ /// isSpecificPlaceholderType - Test for a specific placeholder type.
+ bool isSpecificPlaceholderType(unsigned K) const;
+
/// isIntegerType() does *not* include complex integers (a GCC extension).
/// isComplexIntegerType() can be used to test for complex integers.
bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum)
@@ -1207,6 +1240,8 @@ public:
bool isDerivedType() const; // C99 6.2.5p20
bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
bool isAggregateType() const;
+ bool isFundamentalType() const;
+ bool isCompoundType() const;
// Type Predicates: Check to see if this type is structurally the specified
// type, ignoring typedefs and qualifiers.
@@ -1321,6 +1356,7 @@ public:
// for object declared using an interface.
const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
+ const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
@@ -1475,25 +1511,52 @@ public:
NullPtr, // This is the type of C++0x 'nullptr'.
+ /// The primitive Objective C 'id' type. The user-visible 'id'
+ /// type is a typedef of an ObjCObjectPointerType to an
+ /// ObjCObjectType with this as its base. In fact, this only ever
+ /// shows up in an AST as the base type of an ObjCObjectType.
+ ObjCId,
+
+ /// The primitive Objective C 'Class' type. The user-visible
+ /// 'Class' type is a typedef of an ObjCObjectPointerType to an
+ /// ObjCObjectType with this as its base. In fact, this only ever
+ /// shows up in an AST as the base type of an ObjCObjectType.
+ ObjCClass,
+
+ /// The primitive Objective C 'SEL' type. The user-visible 'SEL'
+ /// type is a typedef of a PointerType to this.
+ ObjCSel,
+
/// This represents the type of an expression whose type is
/// totally unknown, e.g. 'T::foo'. It is permitted for this to
/// appear in situations where the structure of the type is
/// theoretically deducible.
Dependent,
- Overload, // This represents the type of an overloaded function declaration.
-
- /// The primitive Objective C 'id' type. The type pointed to by the
- /// user-visible 'id' type. Only ever shows up in an AST as the base
- /// type of an ObjCObjectType.
- ObjCId,
-
- /// The primitive Objective C 'Class' type. The type pointed to by the
- /// user-visible 'Class' type. Only ever shows up in an AST as the
- /// base type of an ObjCObjectType.
- ObjCClass,
-
- ObjCSel // This represents the ObjC 'SEL' type.
+ /// The type of an unresolved overload set. A placeholder type.
+ /// Expressions with this type have one of the following basic
+ /// forms, with parentheses generally permitted:
+ /// foo # possibly qualified, not if an implicit access
+ /// foo # possibly qualified, not if an implicit access
+ /// &foo # possibly qualified, not if an implicit access
+ /// x->foo # only if might be a static member function
+ /// &x->foo # only if might be a static member function
+ /// &Class::foo # when a pointer-to-member; sub-expr also has this type
+ /// OverloadExpr::find can be used to analyze the expression.
+ Overload,
+
+ /// The type of a bound C++ non-static member function.
+ /// A placeholder type. Expressions with this type have one of the
+ /// following basic forms:
+ /// foo # if an implicit access
+ /// x->foo # if only contains non-static members
+ BoundMember,
+
+ /// __builtin_any_type. A placeholder type. Useful for clients
+ /// like debuggers that don't know what type to give something.
+ /// Only a small number of operations are valid on expressions of
+ /// unknown type, most notably explicit casts.
+ UnknownAny
};
public:
@@ -1526,11 +1589,11 @@ public:
return getKind() >= Float && getKind() <= LongDouble;
}
- /// Determines whether this type is a "forbidden" placeholder type,
- /// i.e. a type which cannot appear in arbitrary positions in a
- /// fully-formed expression.
+ /// Determines whether this type is a placeholder type, i.e. a type
+ /// which cannot appear in arbitrary positions in a fully-formed
+ /// expression.
bool isPlaceholderType() const {
- return getKind() == Overload;
+ return getKind() >= Overload;
}
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
@@ -1991,7 +2054,7 @@ public:
friend class StmtIteratorBase;
void Profile(llvm::FoldingSetNodeID &ID) {
- assert(0 && "Cannnot unique VariableArrayTypes.");
+ assert(0 && "Cannot unique VariableArrayTypes.");
}
};
@@ -2257,12 +2320,13 @@ class FunctionType : public Type {
// you'll need to adjust both the Bits field below and
// Type::FunctionTypeBitfields.
- // | CC |noreturn|regparm
- // |0 .. 2| 3 |4 .. 6
+ // | CC |noreturn|hasregparm|regparm
+ // |0 .. 2| 3 | 4 |5 .. 7
enum { CallConvMask = 0x7 };
enum { NoReturnMask = 0x8 };
+ enum { HasRegParmMask = 0x10 };
enum { RegParmMask = ~(CallConvMask | NoReturnMask),
- RegParmOffset = 4 };
+ RegParmOffset = 5 };
unsigned char Bits;
@@ -2273,9 +2337,10 @@ class FunctionType : public Type {
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, unsigned regParm, CallingConv cc) {
+ ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc) {
Bits = ((unsigned) cc) |
(noReturn ? NoReturnMask : 0) |
+ (hasRegParm ? HasRegParmMask : 0) |
(regParm << RegParmOffset);
}
@@ -2284,6 +2349,7 @@ 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; }
CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
@@ -2305,7 +2371,7 @@ class FunctionType : public Type {
}
ExtInfo withRegParm(unsigned RegParm) const {
- return ExtInfo((Bits & ~RegParmMask) | (RegParm << RegParmOffset));
+ return ExtInfo(HasRegParmMask | (Bits & ~RegParmMask) | (RegParm << RegParmOffset));
}
ExtInfo withCallingConv(CallingConv cc) const {
@@ -2341,7 +2407,8 @@ protected:
public:
QualType getResultType() const { return ResultType; }
-
+
+ bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
CallingConv getCallConv() const { return getExtInfo().getCC(); }
@@ -2403,17 +2470,17 @@ public:
/// ExtProtoInfo - Extra information about a function prototype.
struct ExtProtoInfo {
ExtProtoInfo() :
- Variadic(false), HasExceptionSpec(false), HasAnyExceptionSpec(false),
- TypeQuals(0), RefQualifier(RQ_None), NumExceptions(0), Exceptions(0) {}
+ Variadic(false), ExceptionSpecType(EST_None), TypeQuals(0),
+ RefQualifier(RQ_None), NumExceptions(0), Exceptions(0), NoexceptExpr(0) {}
FunctionType::ExtInfo ExtInfo;
bool Variadic;
- bool HasExceptionSpec;
- bool HasAnyExceptionSpec;
+ ExceptionSpecificationType ExceptionSpecType;
unsigned char TypeQuals;
RefQualifierKind RefQualifier;
unsigned NumExceptions;
const QualType *Exceptions;
+ Expr *NoexceptExpr;
};
private:
@@ -2435,13 +2502,10 @@ private:
unsigned NumArgs : 20;
/// NumExceptions - The number of types in the exception spec, if any.
- unsigned NumExceptions : 10;
+ unsigned NumExceptions : 9;
- /// HasExceptionSpec - Whether this function has an exception spec at all.
- unsigned HasExceptionSpec : 1;
-
- /// HasAnyExceptionSpec - Whether this function has a throw(...) spec.
- unsigned HasAnyExceptionSpec : 1;
+ /// ExceptionSpecType - The type of exception specification this function has.
+ unsigned ExceptionSpecType : 3;
/// ArgInfo - There is an variable size array after the class in memory that
/// holds the argument types.
@@ -2449,6 +2513,9 @@ private:
/// Exceptions - There is another variable size array after ArgInfo that
/// holds the exception types.
+ /// NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing
+ /// to the expression in the noexcept() specifier.
+
friend class ASTContext; // ASTContext creates these.
public:
@@ -2462,29 +2529,66 @@ public:
ExtProtoInfo EPI;
EPI.ExtInfo = getExtInfo();
EPI.Variadic = isVariadic();
- EPI.HasExceptionSpec = hasExceptionSpec();
- EPI.HasAnyExceptionSpec = hasAnyExceptionSpec();
+ EPI.ExceptionSpecType = getExceptionSpecType();
EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
EPI.RefQualifier = getRefQualifier();
- EPI.NumExceptions = NumExceptions;
- EPI.Exceptions = exception_begin();
+ if (EPI.ExceptionSpecType == EST_Dynamic) {
+ EPI.NumExceptions = NumExceptions;
+ EPI.Exceptions = exception_begin();
+ } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
+ EPI.NoexceptExpr = getNoexceptExpr();
+ }
return EPI;
}
- bool hasExceptionSpec() const { return HasExceptionSpec; }
- bool hasAnyExceptionSpec() const { return HasAnyExceptionSpec; }
+ /// \brief Get the kind of exception specification on this function.
+ ExceptionSpecificationType getExceptionSpecType() const {
+ return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
+ }
+ /// \brief Return whether this function has any kind of exception spec.
+ bool hasExceptionSpec() const {
+ return getExceptionSpecType() != EST_None;
+ }
+ /// \brief Return whether this function has a dynamic (throw) exception spec.
+ bool hasDynamicExceptionSpec() const {
+ return isDynamicExceptionSpec(getExceptionSpecType());
+ }
+ /// \brief Return whether this function has a noexcept exception spec.
+ bool hasNoexceptExceptionSpec() const {
+ return isNoexceptExceptionSpec(getExceptionSpecType());
+ }
+ /// \brief Result type of getNoexceptSpec().
+ enum NoexceptResult {
+ NR_NoNoexcept, ///< There is no noexcept specifier.
+ NR_BadNoexcept, ///< The noexcept specifier has a bad expression.
+ NR_Dependent, ///< The noexcept specifier is dependent.
+ NR_Throw, ///< The noexcept specifier evaluates to false.
+ NR_Nothrow ///< The noexcept specifier evaluates to true.
+ };
+ /// \brief Get the meaning of the noexcept spec on this function, if any.
+ NoexceptResult getNoexceptSpec(ASTContext &Ctx) const;
unsigned getNumExceptions() const { return NumExceptions; }
QualType getExceptionType(unsigned i) const {
assert(i < NumExceptions && "Invalid exception number!");
return exception_begin()[i];
}
- bool hasEmptyExceptionSpec() const {
- return hasExceptionSpec() && !hasAnyExceptionSpec() &&
- getNumExceptions() == 0;
+ Expr *getNoexceptExpr() const {
+ if (getExceptionSpecType() != EST_ComputedNoexcept)
+ return 0;
+ // NoexceptExpr sits where the arguments end.
+ return *reinterpret_cast<Expr *const *>(arg_type_end());
+ }
+ bool isNothrow(ASTContext &Ctx) const {
+ ExceptionSpecificationType EST = getExceptionSpecType();
+ if (EST == EST_DynamicNone || EST == EST_BasicNoexcept)
+ return true;
+ if (EST != EST_ComputedNoexcept)
+ return false;
+ return getNoexceptSpec(Ctx) == NR_Nothrow;
}
using FunctionType::isVariadic;
-
+
/// \brief Determines whether this function prototype contains a
/// parameter pack at the end.
///
@@ -2513,6 +2617,8 @@ public:
return arg_type_end();
}
exception_iterator exception_end() const {
+ if (getExceptionSpecType() != EST_Dynamic)
+ return exception_begin();
return exception_begin() + NumExceptions;
}
@@ -2524,10 +2630,10 @@ public:
}
static bool classof(const FunctionProtoType *) { return true; }
- void Profile(llvm::FoldingSetNodeID &ID);
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
arg_type_iterator ArgTys, unsigned NumArgs,
- const ExtProtoInfo &EPI);
+ const ExtProtoInfo &EPI, const ASTContext &Context);
};
@@ -2566,18 +2672,18 @@ public:
class TypedefType : public Type {
- TypedefDecl *Decl;
+ TypedefNameDecl *Decl;
protected:
- TypedefType(TypeClass tc, const TypedefDecl *D, QualType can)
+ TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
: Type(tc, can, can->isDependentType(), can->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false),
- Decl(const_cast<TypedefDecl*>(D)) {
+ Decl(const_cast<TypedefNameDecl*>(D)) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
friend class ASTContext; // ASTContext creates these.
public:
- TypedefDecl *getDecl() const { return Decl; }
+ TypedefNameDecl *getDecl() const { return Decl; }
bool isSugared() const { return true; }
QualType desugar() const;
@@ -2807,9 +2913,10 @@ public:
// Enumerated operand (string or keyword).
attr_objc_gc,
+ attr_pcs,
FirstEnumOperandKind = attr_objc_gc,
- LastEnumOperandKind = attr_objc_gc,
+ LastEnumOperandKind = attr_pcs,
// No operand.
attr_noreturn,
@@ -2864,44 +2971,68 @@ public:
};
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
- unsigned Depth : 15;
- unsigned ParameterPack : 1;
- unsigned Index : 16;
- IdentifierInfo *Name;
+ // Helper data collector for canonical types.
+ struct CanonicalTTPTInfo {
+ unsigned Depth : 15;
+ unsigned ParameterPack : 1;
+ unsigned Index : 16;
+ };
+
+ union {
+ // Info for the canonical type.
+ CanonicalTTPTInfo CanTTPTInfo;
+ // Info for the non-canonical type.
+ TemplateTypeParmDecl *TTPDecl;
+ };
- TemplateTypeParmType(unsigned D, unsigned I, bool PP, IdentifierInfo *N,
- QualType Canon)
+ /// Build a non-canonical type.
+ TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
: Type(TemplateTypeParm, Canon, /*Dependent=*/true,
- /*VariablyModified=*/false, PP),
- Depth(D), ParameterPack(PP), Index(I), Name(N) { }
+ /*VariablyModified=*/false,
+ Canon->containsUnexpandedParameterPack()),
+ TTPDecl(TTPDecl) { }
+ /// Build the canonical type.
TemplateTypeParmType(unsigned D, unsigned I, bool PP)
: Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true,
- /*VariablyModified=*/false, PP),
- Depth(D), ParameterPack(PP), Index(I), Name(0) { }
+ /*VariablyModified=*/false, PP) {
+ CanTTPTInfo.Depth = D;
+ CanTTPTInfo.Index = I;
+ CanTTPTInfo.ParameterPack = PP;
+ }
friend class ASTContext; // ASTContext creates these
+ const CanonicalTTPTInfo& getCanTTPTInfo() const {
+ QualType Can = getCanonicalTypeInternal();
+ return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo;
+ }
+
public:
- unsigned getDepth() const { return Depth; }
- unsigned getIndex() const { return Index; }
- bool isParameterPack() const { return ParameterPack; }
- IdentifierInfo *getName() const { return Name; }
+ unsigned getDepth() const { return getCanTTPTInfo().Depth; }
+ unsigned getIndex() const { return getCanTTPTInfo().Index; }
+ bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; }
+
+ TemplateTypeParmDecl *getDecl() const {
+ return isCanonicalUnqualified() ? 0 : TTPDecl;
+ }
+
+ IdentifierInfo *getIdentifier() const;
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Depth, Index, ParameterPack, Name);
+ Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl());
}
static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
unsigned Index, bool ParameterPack,
- IdentifierInfo *Name) {
+ TemplateTypeParmDecl *TTPDecl) {
ID.AddInteger(Depth);
ID.AddInteger(Index);
ID.AddBoolean(ParameterPack);
- ID.AddPointer(Name);
+ ID.AddPointer(TTPDecl);
}
static bool classof(const Type *T) {
@@ -2930,8 +3061,6 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
public:
- IdentifierInfo *getName() const { return Replaced->getName(); }
-
/// Gets the template parameter that was substituted for.
const TemplateTypeParmType *getReplacedParameter() const {
return Replaced;
@@ -2992,7 +3121,7 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
public:
- IdentifierInfo *getName() const { return Replaced->getName(); }
+ IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
/// Gets the template parameter that was substituted for.
const TemplateTypeParmType *getReplacedParameter() const {
@@ -4064,12 +4193,6 @@ inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
return getFunctionExtInfo(*t);
}
-/// \brief Determine whether this set of qualifiers is a superset of the given
-/// set of qualifiers.
-inline bool Qualifiers::isSupersetOf(Qualifiers Other) const {
- return Mask != Other.Mask && (Mask | Other.Mask) == Mask;
-}
-
/// isMoreQualifiedThan - Determine whether this type is more
/// qualified than the Other type. For example, "const volatile int"
/// is more qualified than "const int", "volatile int", and
@@ -4105,6 +4228,40 @@ inline QualType QualType::getNonReferenceType() const {
return *this;
}
+/// \brief Tests whether the type is categorized as a fundamental type.
+///
+/// \returns True for types specified in C++0x [basic.fundamental].
+inline bool Type::isFundamentalType() const {
+ return isVoidType() ||
+ // FIXME: It's really annoying that we don't have an
+ // 'isArithmeticType()' which agrees with the standard definition.
+ (isArithmeticType() && !isEnumeralType());
+}
+
+/// \brief Tests whether the type is categorized as a compound type.
+///
+/// \returns True for types specified in C++0x [basic.compound].
+inline bool Type::isCompoundType() const {
+ // C++0x [basic.compound]p1:
+ // Compound types can be constructed in the following ways:
+ // -- arrays of objects of a given type [...];
+ return isArrayType() ||
+ // -- functions, which have parameters of given types [...];
+ isFunctionType() ||
+ // -- pointers to void or objects or functions [...];
+ isPointerType() ||
+ // -- references to objects or functions of a given type. [...]
+ isReferenceType() ||
+ // -- classes containing a sequence of objects of various types, [...];
+ isRecordType() ||
+ // -- unions, which ar classes capable of containing objects of different types at different times;
+ isUnionType() ||
+ // -- enumerations, which comprise a set of named constant values. [...];
+ isEnumeralType() ||
+ // -- pointers to non-static class members, [...].
+ isMemberPointerType();
+}
+
inline bool Type::isFunctionType() const {
return isa<FunctionType>(CanonicalType);
}
@@ -4236,6 +4393,12 @@ inline bool Type::isPlaceholderType() const {
return false;
}
+inline bool Type::isSpecificPlaceholderType(unsigned K) const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+ return (BT->getKind() == (BuiltinType::Kind) K);
+ return false;
+}
+
/// \brief Determines whether this is a type for which one can define
/// an overloaded operator.
inline bool Type::isOverloadableType() const {
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index c7f5ee76330c..a1df744c2a72 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -527,7 +527,7 @@ class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TypedefTypeLoc,
TypedefType> {
public:
- TypedefDecl *getTypedefDecl() const {
+ TypedefNameDecl *getTypedefNameDecl() const {
return getTypePtr()->getDecl();
}
};
@@ -584,6 +584,8 @@ class TemplateTypeParmTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TemplateTypeParmTypeLoc,
TemplateTypeParmType> {
+public:
+ TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
/// \brief Wrapper for substituted template type parameters.
@@ -943,10 +945,14 @@ public:
}
};
+struct MemberPointerLocInfo : public PointerLikeLocInfo {
+ TypeSourceInfo *ClassTInfo;
+};
/// \brief Wrapper for source info for member pointers.
class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
- MemberPointerType> {
+ MemberPointerType,
+ MemberPointerLocInfo> {
public:
SourceLocation getStarLoc() const {
return getSigilLoc();
@@ -954,6 +960,28 @@ public:
void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
+
+ const Type *getClass() const {
+ return getTypePtr()->getClass();
+ }
+ TypeSourceInfo *getClassTInfo() const {
+ return getLocalData()->ClassTInfo;
+ }
+ void setClassTInfo(TypeSourceInfo* TI) {
+ getLocalData()->ClassTInfo = TI;
+ }
+
+ void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+ setSigilLoc(Loc);
+ setClassTInfo(0);
+ }
+
+ SourceRange getLocalSourceRange() const {
+ if (TypeSourceInfo *TI = getClassTInfo())
+ return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
+ else
+ return SourceRange(getStarLoc());
+ }
};
/// Wraps an ObjCPointerType with source location information.
@@ -1007,7 +1035,8 @@ public:
struct FunctionLocInfo {
- SourceLocation LParenLoc, RParenLoc;
+ SourceLocation LocalRangeBegin;
+ SourceLocation LocalRangeEnd;
bool TrailingReturn;
};
@@ -1017,18 +1046,18 @@ class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
FunctionType,
FunctionLocInfo> {
public:
- SourceLocation getLParenLoc() const {
- return getLocalData()->LParenLoc;
+ SourceLocation getLocalRangeBegin() const {
+ return getLocalData()->LocalRangeBegin;
}
- void setLParenLoc(SourceLocation Loc) {
- getLocalData()->LParenLoc = Loc;
+ void setLocalRangeBegin(SourceLocation L) {
+ getLocalData()->LocalRangeBegin = L;
}
- SourceLocation getRParenLoc() const {
- return getLocalData()->RParenLoc;
+ SourceLocation getLocalRangeEnd() const {
+ return getLocalData()->LocalRangeEnd;
}
- void setRParenLoc(SourceLocation Loc) {
- getLocalData()->RParenLoc = Loc;
+ void setLocalRangeEnd(SourceLocation L) {
+ getLocalData()->LocalRangeEnd = L;
}
bool getTrailingReturn() const {
@@ -1056,12 +1085,12 @@ public:
}
SourceRange getLocalSourceRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
+ return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setLParenLoc(Loc);
- setRParenLoc(Loc);
+ setLocalRangeBegin(Loc);
+ setLocalRangeEnd(Loc);
setTrailingReturn(false);
for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
setArg(i, NULL);
@@ -1388,7 +1417,10 @@ class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
struct ElaboratedLocInfo {
SourceLocation KeywordLoc;
- SourceRange QualifierRange;
+
+ /// \brief Opaque data pointer used to reconstruct a nested-name-specifier
+ /// from
+ void *QualifierData;
};
class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
@@ -1403,27 +1435,29 @@ public:
this->getLocalData()->KeywordLoc = Loc;
}
- SourceRange getQualifierRange() const {
- return this->getLocalData()->QualifierRange;
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
+ getLocalData()->QualifierData);
}
- void setQualifierRange(SourceRange Range) {
- this->getLocalData()->QualifierRange = Range;
+
+ void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
+ assert(QualifierLoc.getNestedNameSpecifier()
+ == getTypePtr()->getQualifier() &&
+ "Inconsistent nested-name-specifier pointer");
+ getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
SourceRange getLocalSourceRange() const {
if (getKeywordLoc().isValid())
- if (getQualifierRange().getEnd().isValid())
- return SourceRange(getKeywordLoc(), getQualifierRange().getEnd());
+ if (getQualifierLoc())
+ return SourceRange(getKeywordLoc(), getQualifierLoc().getEndLoc());
else
return SourceRange(getKeywordLoc());
else
- return getQualifierRange();
+ return getQualifierLoc().getSourceRange();
}
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setKeywordLoc(Loc);
- setQualifierRange(SourceRange(Loc));
- }
+ void initializeLocal(ASTContext &Context, SourceLocation Loc);
TypeLoc getNamedTypeLoc() const {
return getInnerTypeLoc();
@@ -1444,6 +1478,9 @@ public:
// type is some sort of TypeDeclTypeLoc.
struct DependentNameLocInfo : ElaboratedLocInfo {
SourceLocation NameLoc;
+
+ /// \brief Data associated with the nested-name-specifier location.
+ void *QualifierData;
};
class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
@@ -1458,13 +1495,18 @@ public:
this->getLocalData()->KeywordLoc = Loc;
}
- SourceRange getQualifierRange() const {
- return this->getLocalData()->QualifierRange;
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
+ getLocalData()->QualifierData);
}
- void setQualifierRange(SourceRange Range) {
- this->getLocalData()->QualifierRange = Range;
+
+ void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
+ assert(QualifierLoc.getNestedNameSpecifier()
+ == getTypePtr()->getQualifier() &&
+ "Inconsistent nested-name-specifier pointer");
+ getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
-
+
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
}
@@ -1476,7 +1518,7 @@ public:
if (getKeywordLoc().isValid())
return SourceRange(getKeywordLoc(), getNameLoc());
else
- return SourceRange(getQualifierRange().getBegin(), getNameLoc());
+ return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
}
void copy(DependentNameTypeLoc Loc) {
@@ -1485,16 +1527,11 @@ public:
memcpy(Data, Loc.Data, size);
}
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setKeywordLoc(Loc);
- setQualifierRange(SourceRange(Loc));
- setNameLoc(Loc);
- }
+ void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
-// This is exactly the structure of an ElaboratedTypeLoc whose inner
-// type is some sort of TemplateSpecializationTypeLoc.
struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
+ SourceLocation KeywordLoc;
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
// followed by a TemplateArgumentLocInfo[]
@@ -1513,11 +1550,28 @@ public:
this->getLocalData()->KeywordLoc = Loc;
}
- SourceRange getQualifierRange() const {
- return this->getLocalData()->QualifierRange;
- }
- void setQualifierRange(SourceRange Range) {
- this->getLocalData()->QualifierRange = Range;
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ if (!getLocalData()->QualifierData)
+ return NestedNameSpecifierLoc();
+
+ return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
+ getLocalData()->QualifierData);
+ }
+
+ void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
+ if (!QualifierLoc) {
+ // Even if we have a nested-name-specifier in the dependent
+ // template specialization type, we won't record the nested-name-specifier
+ // location information when this type-source location information is
+ // part of a nested-name-specifier.
+ getLocalData()->QualifierData = 0;
+ return;
+ }
+
+ assert(QualifierLoc.getNestedNameSpecifier()
+ == getTypePtr()->getQualifier() &&
+ "Inconsistent nested-name-specifier pointer");
+ getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
SourceLocation getNameLoc() const {
@@ -1559,8 +1613,10 @@ public:
SourceRange getLocalSourceRange() const {
if (getKeywordLoc().isValid())
return SourceRange(getKeywordLoc(), getRAngleLoc());
+ else if (getQualifierLoc())
+ return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
else
- return SourceRange(getQualifierRange().getBegin(), getRAngleLoc());
+ return SourceRange(getNameLoc(), getRAngleLoc());
}
void copy(DependentTemplateSpecializationTypeLoc Loc) {
@@ -1569,16 +1625,7 @@ public:
memcpy(Data, Loc.Data, size);
}
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setKeywordLoc(Loc);
- setQualifierRange(SourceRange(Loc));
- setNameLoc(Loc);
- setLAngleLoc(Loc);
- setRAngleLoc(Loc);
- TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
- getTypePtr()->getArgs(),
- getArgInfos(), Loc);
- }
+ void initializeLocal(ASTContext &Context, SourceLocation Loc);
unsigned getExtraLocalDataSize() const {
return getNumArgs() * sizeof(TemplateArgumentLocInfo);