summaryrefslogtreecommitdiffstats
path: root/include/clang/AST
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2010-09-17 15:54:40 +0000
committerdim <dim@FreeBSD.org>2010-09-17 15:54:40 +0000
commit36c49e3f258dced101949edabd72e9bc3f1dedc4 (patch)
tree0bbe07708f7571f8b5291f6d7b96c102b7c99dee /include/clang/AST
parentfc84956ac8b7cd244ef30e7a4d4d38a58dec5904 (diff)
downloadFreeBSD-src-36c49e3f258dced101949edabd72e9bc3f1dedc4.zip
FreeBSD-src-36c49e3f258dced101949edabd72e9bc3f1dedc4.tar.gz
Vendor import of clang r114020 (from the release_28 branch):
http://llvm.org/svn/llvm-project/cfe/branches/release_28@114020 Approved by: rpaulo (mentor)
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTConsumer.h14
-rw-r--r--include/clang/AST/ASTContext.h81
-rw-r--r--include/clang/AST/ASTImporter.h2
-rw-r--r--include/clang/AST/Attr.h607
-rw-r--r--include/clang/AST/CMakeLists.txt6
-rw-r--r--include/clang/AST/CanonicalType.h9
-rw-r--r--include/clang/AST/Decl.h238
-rw-r--r--include/clang/AST/DeclBase.h181
-rw-r--r--include/clang/AST/DeclCXX.h279
-rw-r--r--include/clang/AST/DeclContextInternals.h160
-rw-r--r--include/clang/AST/DeclFriend.h16
-rw-r--r--include/clang/AST/DeclGroup.h1
-rw-r--r--include/clang/AST/DeclObjC.h150
-rw-r--r--include/clang/AST/DeclTemplate.h679
-rw-r--r--include/clang/AST/DeclarationName.h147
-rw-r--r--include/clang/AST/Expr.h748
-rw-r--r--include/clang/AST/ExprCXX.h405
-rw-r--r--include/clang/AST/ExternalASTSource.h93
-rw-r--r--include/clang/AST/FullExpr.h1
-rw-r--r--include/clang/AST/Makefile8
-rw-r--r--include/clang/AST/NestedNameSpecifier.h2
-rw-r--r--include/clang/AST/OperationKinds.h158
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h318
-rw-r--r--include/clang/AST/Redeclarable.h3
-rw-r--r--include/clang/AST/Stmt.h37
-rw-r--r--include/clang/AST/StmtCXX.h38
-rw-r--r--include/clang/AST/StmtVisitor.h107
-rw-r--r--include/clang/AST/Type.h143
-rw-r--r--include/clang/AST/TypeLoc.h4
-rw-r--r--include/clang/AST/TypeOrdering.h21
30 files changed, 2606 insertions, 2050 deletions
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 0611395..84833c0 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -18,9 +18,10 @@ namespace clang {
class ASTContext;
class CXXRecordDecl;
class DeclGroupRef;
- class TagDecl;
class HandleTagDeclDefinition;
+ class ASTDeserializationListener; // layering violation because void* is ugly
class SemaConsumer; // layering violation required for safe SemaConsumer
+ class TagDecl;
class VarDecl;
/// ASTConsumer - This is an abstract interface that should be implemented by
@@ -48,6 +49,11 @@ public:
/// elements). Use Decl::getNextDeclarator() to walk the chain.
virtual void HandleTopLevelDecl(DeclGroupRef D);
+ /// HandleInterestingDecl - Handle the specified interesting declaration. This
+ /// is called by the AST reader when deserializing things that might interest
+ /// the consumer. The default implementation forwards to HandleTopLevelDecl.
+ virtual void HandleInterestingDecl(DeclGroupRef D);
+
/// HandleTranslationUnit - This method is called when the ASTs for entire
/// translation unit have been parsed.
virtual void HandleTranslationUnit(ASTContext &Ctx) {}
@@ -80,6 +86,12 @@ public:
/// it was actually used.
virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {}
+ /// \brief If the consumer is interested in entities being deserialized from
+ /// AST files, it should return a pointer to a ASTDeserializationListener here
+ ///
+ /// The return type is void* because ASTDS lives in Frontend.
+ virtual ASTDeserializationListener *GetASTDeserializationListener() { return 0; }
+
/// PrintStats - If desired, print any statistics.
virtual void PrintStats() {}
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 3799451..ae4ee94 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -18,7 +18,6 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
@@ -50,6 +49,7 @@ namespace clang {
class SelectorTable;
class SourceManager;
class TargetInfo;
+ class CXXABI;
// Decls
class DeclContext;
class CXXMethodDecl;
@@ -198,7 +198,7 @@ class ASTContext {
///
/// Since so few decls have attrs, we keep them in a hash map instead of
/// wasting space in the Decl class.
- llvm::DenseMap<const Decl*, Attr*> DeclAttrs;
+ llvm::DenseMap<const Decl*, AttrVec*> DeclAttrs;
/// \brief Keeps track of the static data member templates from which
/// static data members of class template specializations were instantiated.
@@ -275,13 +275,18 @@ class ASTContext {
/// this ASTContext object.
LangOptions LangOpts;
- /// MallocAlloc/BumpAlloc - The allocator objects used to create AST objects.
- bool FreeMemory;
- llvm::MallocAllocator MallocAlloc;
+ /// \brief The allocator used to create AST objects.
+ ///
+ /// AST objects are never destructed; rather, all memory associated with the
+ /// AST objects will be released when the ASTContext itself is destroyed.
llvm::BumpPtrAllocator BumpAlloc;
/// \brief Allocator for partial diagnostics.
PartialDiagnostic::StorageAllocator DiagAllocator;
+
+ /// \brief The current C++ ABI.
+ llvm::OwningPtr<CXXABI> ABI;
+ CXXABI *createCXXABI(const TargetInfo &T);
public:
const TargetInfo &Target;
@@ -301,13 +306,9 @@ public:
SourceManager& getSourceManager() { return SourceMgr; }
const SourceManager& getSourceManager() const { return SourceMgr; }
void *Allocate(unsigned Size, unsigned Align = 8) {
- return FreeMemory ? MallocAlloc.Allocate(Size, Align) :
- BumpAlloc.Allocate(Size, Align);
- }
- void Deallocate(void *Ptr) {
- if (FreeMemory)
- MallocAlloc.Deallocate(Ptr);
+ return BumpAlloc.Allocate(Size, Align);
}
+ void Deallocate(void *Ptr) { }
PartialDiagnostic::StorageAllocator &getDiagAllocator() {
return DiagAllocator;
@@ -320,10 +321,10 @@ public:
}
/// \brief Retrieve the attributes for the given declaration.
- Attr*& getDeclAttrs(const Decl *D) { return DeclAttrs[D]; }
+ AttrVec& getDeclAttrs(const Decl *D);
/// \brief Erase the attributes corresponding to the given declaration.
- void eraseDeclAttrs(const Decl *D) { DeclAttrs.erase(D); }
+ void eraseDeclAttrs(const Decl *D);
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
@@ -393,7 +394,7 @@ public:
ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,
IdentifierTable &idents, SelectorTable &sels,
Builtin::Context &builtins,
- bool FreeMemory = true, unsigned size_reserve=0);
+ unsigned size_reserve);
~ASTContext();
@@ -520,7 +521,7 @@ public:
llvm::SmallVectorImpl<const Expr *> &Layout);
/// This builds the struct used for __block variables.
- QualType BuildByRefType(const char *DeclName, QualType Ty);
+ QualType BuildByRefType(llvm::StringRef DeclName, QualType Ty);
/// Returns true iff we need copy/dispose helpers for the given type.
bool BlockRequiresCopying(QualType Ty);
@@ -873,7 +874,8 @@ public:
return getExtQualType(T, Qs);
}
- DeclarationName getNameForTemplate(TemplateName Name);
+ DeclarationNameInfo getNameForTemplate(TemplateName Name,
+ SourceLocation NameLoc);
TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin,
UnresolvedSetIterator End);
@@ -909,6 +911,11 @@ public:
///
Qualifiers::GC getObjCGCAttrKind(const QualType &Ty) const;
+ /// areCompatibleVectorTypes - Return true if the given vector types either
+ /// are of the same unqualified type or if one is GCC and other - equivalent
+ /// AltiVec vector type.
+ bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec);
+
/// isObjCNSObjectType - Return true if this is an NSObject object with
/// its NSObject attribute set.
bool isObjCNSObjectType(QualType Ty) const;
@@ -1002,13 +1009,12 @@ public:
/// of class definition.
const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
- void CollectObjCIvars(const ObjCInterfaceDecl *OI,
- llvm::SmallVectorImpl<FieldDecl*> &Fields);
-
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
- void CollectNonClassIvars(const ObjCInterfaceDecl *OI,
- llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+
+ void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
+ llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+
unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI);
void CollectInheritedProtocols(const Decl *CDecl,
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
@@ -1067,8 +1073,6 @@ public:
bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
- /// \brief Retrieves the "canonical" declaration of
-
/// \brief Retrieves the "canonical" nested name specifier for a
/// given nested name specifier.
///
@@ -1218,7 +1222,8 @@ public:
//===--------------------------------------------------------------------===//
/// Compatibility predicates used to check assignment expressions.
- bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
+ bool typesAreCompatible(QualType T1, QualType T2,
+ bool CompareUnqualified = false); // C99 6.2.7p1
bool typesAreBlockPointerCompatible(QualType, QualType);
@@ -1235,6 +1240,8 @@ public:
bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
bool ForCompare);
+ bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS);
+
// Check the safety of assignment from LHS to RHS
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
@@ -1246,10 +1253,13 @@ public:
bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
-
+ bool canBindObjCObjectType(QualType To, QualType From);
+
// Functions for calculating composite types
- QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false);
- QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false);
+ QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
+ bool Unqualified = false);
+ QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
+ bool Unqualified = false);
QualType mergeObjCGCQualifiers(QualType, QualType);
@@ -1257,6 +1267,10 @@ public:
/// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9)
/// and returns the result type of that conversion.
QualType UsualArithmeticConversionsType(QualType lhs, QualType rhs);
+
+ void ResetObjCLayout(const ObjCContainerDecl *CD) {
+ ObjCLayouts[CD] = 0;
+ }
//===--------------------------------------------------------------------===//
// Integer Predicates
@@ -1337,6 +1351,17 @@ public:
/// when it is called.
void AddDeallocation(void (*Callback)(void*), void *Data);
+ GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD);
+ GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
+
+ /// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH
+ /// lazily, only when used; this is only relevant for function or file scoped
+ /// var definitions.
+ ///
+ /// \returns true if the function/var must be CodeGen'ed/deserialized even if
+ /// it is not used.
+ bool DeclMustBeEmitted(const Decl *D);
+
//===--------------------------------------------------------------------===//
// Statistics
//===--------------------------------------------------------------------===//
@@ -1386,7 +1411,7 @@ private:
const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
-
+
private:
/// \brief A set of deallocations that should be performed when the
/// ASTContext is destroyed.
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index 7975c43..9380058 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -14,8 +14,8 @@
#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
#define LLVM_CLANG_AST_ASTIMPORTER_H
-#include "clang/AST/Type.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 9faa62e..62ca49f 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -15,8 +15,11 @@
#define LLVM_CLANG_AST_ATTR_H
#include "llvm/Support/Casting.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "clang/Basic/AttrKinds.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
#include <cassert>
#include <cstring>
#include <algorithm>
@@ -27,28 +30,39 @@ namespace clang {
class IdentifierInfo;
class ObjCInterfaceDecl;
class Expr;
+ class QualType;
+ class FunctionDecl;
+ class TypeSourceInfo;
}
// Defined in ASTContext.h
void *operator new(size_t Bytes, clang::ASTContext &C,
size_t Alignment = 16) throw ();
+// FIXME: Being forced to not have a default argument here due to redeclaration
+// rules on default arguments sucks
+void *operator new[](size_t Bytes, clang::ASTContext &C,
+ size_t Alignment) throw ();
// It is good practice to pair new/delete operators. Also, MSVC gives many
// warnings if a matching delete overload is not declared, even though the
// throw() spec guarantees it will not be implicitly called.
void operator delete(void *Ptr, clang::ASTContext &C, size_t)
throw ();
+void operator delete[](void *Ptr, clang::ASTContext &C, size_t)
+ throw ();
namespace clang {
/// Attr - This represents one attribute.
class Attr {
private:
- Attr *Next;
- attr::Kind AttrKind;
+ SourceLocation Loc;
+ unsigned AttrKind : 16;
bool Inherited : 1;
protected:
+ virtual ~Attr();
+
void* operator new(size_t bytes) throw() {
assert(0 && "Attrs cannot be allocated with regular 'new'.");
return 0;
@@ -57,41 +71,36 @@ protected:
assert(0 && "Attrs cannot be released with regular 'delete'.");
}
-protected:
- Attr(attr::Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
- virtual ~Attr() {
- assert(Next == 0 && "Destroy didn't work");
+public:
+ // Forward so that the regular new and delete do not hide global ones.
+ void* operator new(size_t Bytes, ASTContext &C,
+ size_t Alignment = 16) throw() {
+ return ::operator new(Bytes, C, Alignment);
}
+ void operator delete(void *Ptr, ASTContext &C,
+ size_t Alignment) throw() {
+ return ::operator delete(Ptr, C, Alignment);
+ }
+
+protected:
+ Attr(attr::Kind AK, SourceLocation L)
+ : Loc(L), AttrKind(AK), Inherited(false) {}
+
public:
- virtual void Destroy(ASTContext &C);
/// \brief Whether this attribute should be merged to new
/// declarations.
virtual bool isMerged() const { return true; }
- attr::Kind getKind() const { return AttrKind; }
-
- Attr *getNext() { return Next; }
- const Attr *getNext() const { return Next; }
- void setNext(Attr *next) { Next = next; }
-
- template<typename T> const T *getNext() const {
- for (const Attr *attr = getNext(); attr; attr = attr->getNext())
- if (const T *V = dyn_cast<T>(attr))
- return V;
- return 0;
+ attr::Kind getKind() const {
+ return static_cast<attr::Kind>(AttrKind);
}
- bool isInherited() const { return Inherited; }
- void setInherited(bool value) { Inherited = value; }
-
- void addAttr(Attr *attr) {
- assert((attr != 0) && "addAttr(): attr is null");
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
- // FIXME: This doesn't preserve the order in any way.
- attr->Next = Next;
- Next = attr;
- }
+ bool isInherited() const { return Inherited; }
+ void setInherited(bool I) { Inherited = I; }
// Clone this attribute.
virtual Attr* clone(ASTContext &C) const = 0;
@@ -101,490 +110,112 @@ public:
};
#include "clang/AST/Attrs.inc"
-
-class AttrWithString : public Attr {
-private:
- const char *Str;
- unsigned StrLen;
-protected:
- AttrWithString(attr::Kind AK, ASTContext &C, llvm::StringRef s);
- llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
- void ReplaceString(ASTContext &C, llvm::StringRef newS);
-public:
- virtual void Destroy(ASTContext &C);
-};
-
-#define DEF_SIMPLE_ATTR(ATTR) \
-class ATTR##Attr : public Attr { \
-public: \
- ATTR##Attr() : Attr(attr::ATTR) {} \
- virtual Attr *clone(ASTContext &C) const; \
- static bool classof(const Attr *A) { return A->getKind() == attr::ATTR; } \
- static bool classof(const ATTR##Attr *A) { return true; } \
-}
-DEF_SIMPLE_ATTR(Packed);
-
-/// \brief Attribute for specifying a maximum field alignment; this is only
-/// valid on record decls.
-class MaxFieldAlignmentAttr : public Attr {
- unsigned Alignment;
-
-public:
- MaxFieldAlignmentAttr(unsigned alignment)
- : Attr(attr::MaxFieldAlignment), Alignment(alignment) {}
+/// AttrVec - A vector of Attr, which is how they are stored on the AST.
+typedef llvm::SmallVector<Attr*, 2> AttrVec;
+typedef llvm::SmallVector<const Attr*, 2> ConstAttrVec;
- /// getAlignment - The specified alignment in bits.
- unsigned getAlignment() const { return Alignment; }
-
- virtual Attr* clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::MaxFieldAlignment;
- }
- static bool classof(const MaxFieldAlignmentAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(AlignMac68k);
-
-/// \brief Atribute for specifying the alignment of a variable or type.
-///
-/// This node will either contain the precise Alignment (in bits, not bytes!)
-/// or will contain the expression for the alignment attribute in the case of
-/// a dependent expression within a class or function template. At template
-/// instantiation time these are transformed into concrete attributes.
-class AlignedAttr : public Attr {
- unsigned Alignment;
- Expr *AlignmentExpr;
-public:
- AlignedAttr(unsigned alignment)
- : Attr(attr::Aligned), Alignment(alignment), AlignmentExpr(0) {}
- AlignedAttr(Expr *E)
- : Attr(attr::Aligned), Alignment(0), AlignmentExpr(E) {}
-
- /// getAlignmentExpr - Get a dependent alignment expression if one is present.
- Expr *getAlignmentExpr() const {
- return AlignmentExpr;
- }
-
- /// isDependent - Is the alignment a dependent expression
- bool isDependent() const {
- return getAlignmentExpr();
- }
+/// DestroyAttrs - Destroy the contents of an AttrVec.
+inline void DestroyAttrs (AttrVec& V, ASTContext &C) {
+}
- /// getAlignment - The specified alignment in bits. Requires !isDependent().
- unsigned getAlignment() const {
- assert(!isDependent() && "Cannot get a value dependent alignment");
- return Alignment;
- }
+/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
+/// providing attributes that are of a specifc type.
+template <typename SpecificAttr>
+class specific_attr_iterator {
+ /// Current - The current, underlying iterator.
+ /// In order to ensure we don't dereference an invalid iterator unless
+ /// specifically requested, we don't necessarily advance this all the
+ /// way. Instead, we advance it when an operation is requested; if the
+ /// operation is acting on what should be a past-the-end iterator,
+ /// then we offer no guarantees, but this way we do not dererence a
+ /// past-the-end iterator when we move to a past-the-end position.
+ mutable AttrVec::const_iterator Current;
- /// getMaxAlignment - Get the maximum alignment of attributes on this list.
- unsigned getMaxAlignment() const {
- const AlignedAttr *Next = getNext<AlignedAttr>();
- if (Next)
- return std::max(Next->getMaxAlignment(), getAlignment());
- else
- return getAlignment();
+ void AdvanceToNext() const {
+ while (!llvm::isa<SpecificAttr>(*Current))
+ ++Current;
}
- virtual Attr* clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::Aligned;
+ void AdvanceToNext(AttrVec::const_iterator I) const {
+ while (Current != I && !llvm::isa<SpecificAttr>(*Current))
+ ++Current;
}
- static bool classof(const AlignedAttr *A) { return true; }
-};
-class AnnotateAttr : public AttrWithString {
public:
- AnnotateAttr(ASTContext &C, llvm::StringRef ann)
- : AttrWithString(attr::Annotate, C, ann) {}
-
- llvm::StringRef getAnnotation() const { return getString(); }
+ typedef SpecificAttr* value_type;
+ typedef SpecificAttr* reference;
+ typedef SpecificAttr* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
- virtual Attr* clone(ASTContext &C) const;
+ specific_attr_iterator() : Current() { }
+ explicit specific_attr_iterator(AttrVec::const_iterator i) : Current(i) { }
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::Annotate;
+ reference operator*() const {
+ AdvanceToNext();
+ return llvm::cast<SpecificAttr>(*Current);
}
- static bool classof(const AnnotateAttr *A) { return true; }
-};
-
-class AsmLabelAttr : public AttrWithString {
-public:
- AsmLabelAttr(ASTContext &C, llvm::StringRef L)
- : AttrWithString(attr::AsmLabel, C, L) {}
-
- llvm::StringRef getLabel() const { return getString(); }
-
- virtual Attr* clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::AsmLabel;
- }
- static bool classof(const AsmLabelAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(AlwaysInline);
-
-class AliasAttr : public AttrWithString {
-public:
- AliasAttr(ASTContext &C, llvm::StringRef aliasee)
- : AttrWithString(attr::Alias, C, aliasee) {}
-
- llvm::StringRef getAliasee() const { return getString(); }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Alias; }
- static bool classof(const AliasAttr *A) { return true; }
-};
-
-class ConstructorAttr : public Attr {
- int priority;
-public:
- ConstructorAttr(int p) : Attr(attr::Constructor), priority(p) {}
-
- int getPriority() const { return priority; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A)
- { return A->getKind() == attr::Constructor; }
- static bool classof(const ConstructorAttr *A) { return true; }
-};
-
-class DestructorAttr : public Attr {
- int priority;
-public:
- DestructorAttr(int p) : Attr(attr::Destructor), priority(p) {}
-
- int getPriority() const { return priority; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A)
- { return A->getKind() == attr::Destructor; }
- static bool classof(const DestructorAttr *A) { return true; }
-};
-
-class IBOutletAttr : public Attr {
-public:
- IBOutletAttr() : Attr(attr::IBOutlet) {}
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::IBOutlet;
- }
- static bool classof(const IBOutletAttr *A) { return true; }
-};
-
-class IBOutletCollectionAttr : public Attr {
- const ObjCInterfaceDecl *D;
-public:
- IBOutletCollectionAttr(const ObjCInterfaceDecl *d = 0)
- : Attr(attr::IBOutletCollection), D(d) {}
-
- const ObjCInterfaceDecl *getClass() const { return D; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::IBOutletCollection;
+ pointer operator->() const {
+ AdvanceToNext();
+ return llvm::cast<SpecificAttr>(*Current);
}
- static bool classof(const IBOutletCollectionAttr *A) { return true; }
-};
-
-class IBActionAttr : public Attr {
-public:
- IBActionAttr() : Attr(attr::IBAction) {}
-
- virtual Attr *clone(ASTContext &C) const;
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::IBAction;
+ specific_attr_iterator& operator++() {
+ ++Current;
+ return *this;
}
- static bool classof(const IBActionAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(AnalyzerNoReturn);
-DEF_SIMPLE_ATTR(Deprecated);
-DEF_SIMPLE_ATTR(GNUInline);
-DEF_SIMPLE_ATTR(Malloc);
-DEF_SIMPLE_ATTR(NoReturn);
-DEF_SIMPLE_ATTR(NoInstrumentFunction);
-
-class SectionAttr : public AttrWithString {
-public:
- SectionAttr(ASTContext &C, llvm::StringRef N)
- : AttrWithString(attr::Section, C, N) {}
-
- llvm::StringRef getName() const { return getString(); }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::Section;
+ specific_attr_iterator operator++(int) {
+ specific_attr_iterator Tmp(*this);
+ ++(*this);
+ return Tmp;
}
- static bool classof(const SectionAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(Unavailable);
-DEF_SIMPLE_ATTR(Unused);
-DEF_SIMPLE_ATTR(Used);
-DEF_SIMPLE_ATTR(Weak);
-DEF_SIMPLE_ATTR(WeakImport);
-DEF_SIMPLE_ATTR(WeakRef);
-DEF_SIMPLE_ATTR(NoThrow);
-DEF_SIMPLE_ATTR(Const);
-DEF_SIMPLE_ATTR(Pure);
-
-class NonNullAttr : public Attr {
- unsigned* ArgNums;
- unsigned Size;
-public:
- NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
-
- virtual void Destroy(ASTContext &C);
-
- typedef const unsigned *iterator;
- iterator begin() const { return ArgNums; }
- iterator end() const { return ArgNums + Size; }
- unsigned size() const { return Size; }
- bool isNonNull(unsigned arg) const {
- return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
+ friend bool operator==(specific_attr_iterator Left,
+ specific_attr_iterator Right) {
+ if (Left.Current < Right.Current)
+ Left.AdvanceToNext(Right.Current);
+ else
+ Right.AdvanceToNext(Left.Current);
+ return Left.Current == Right.Current;
}
-
- virtual Attr *clone(ASTContext &C) const;
-
- static bool classof(const Attr *A) { return A->getKind() == attr::NonNull; }
- static bool classof(const NonNullAttr *A) { return true; }
-};
-
-class FormatAttr : public AttrWithString {
- int formatIdx, firstArg;
-public:
- FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
- : AttrWithString(attr::Format, C, type), formatIdx(idx), firstArg(first) {}
-
- llvm::StringRef getType() const { return getString(); }
- void setType(ASTContext &C, llvm::StringRef type);
- int getFormatIdx() const { return formatIdx; }
- int getFirstArg() const { return firstArg; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Format; }
- static bool classof(const FormatAttr *A) { return true; }
-};
-
-class FormatArgAttr : public Attr {
- int formatIdx;
-public:
- FormatArgAttr(int idx) : Attr(attr::FormatArg), formatIdx(idx) {}
- int getFormatIdx() const { return formatIdx; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::FormatArg; }
- static bool classof(const FormatArgAttr *A) { return true; }
-};
-
-class SentinelAttr : public Attr {
- int sentinel, NullPos;
-public:
- SentinelAttr(int sentinel_val, int nullPos) : Attr(attr::Sentinel),
- sentinel(sentinel_val), NullPos(nullPos) {}
- int getSentinel() const { return sentinel; }
- int getNullPos() const { return NullPos; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Sentinel; }
- static bool classof(const SentinelAttr *A) { return true; }
-};
-
-class VisibilityAttr : public Attr {
-public:
- /// @brief An enumeration for the kinds of visibility of symbols.
- enum VisibilityTypes {
- DefaultVisibility = 0,
- HiddenVisibility,
- ProtectedVisibility
- };
-private:
- VisibilityTypes VisibilityType;
-public:
- VisibilityAttr(VisibilityTypes v) : Attr(attr::Visibility),
- VisibilityType(v) {}
-
- VisibilityTypes getVisibility() const { return VisibilityType; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A)
- { return A->getKind() == attr::Visibility; }
- static bool classof(const VisibilityAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(FastCall);
-DEF_SIMPLE_ATTR(StdCall);
-DEF_SIMPLE_ATTR(ThisCall);
-DEF_SIMPLE_ATTR(CDecl);
-DEF_SIMPLE_ATTR(TransparentUnion);
-DEF_SIMPLE_ATTR(ObjCNSObject);
-DEF_SIMPLE_ATTR(ObjCException);
-
-class OverloadableAttr : public Attr {
-public:
- OverloadableAttr() : Attr(attr::Overloadable) { }
-
- virtual bool isMerged() const { return false; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- static bool classof(const Attr *A)
- { return A->getKind() == attr::Overloadable; }
- static bool classof(const OverloadableAttr *) { return true; }
-};
-
-class BlocksAttr : public Attr {
-public:
- enum BlocksAttrTypes {
- ByRef = 0
- };
-private:
- BlocksAttrTypes BlocksAttrType;
-public:
- BlocksAttr(BlocksAttrTypes t) : Attr(attr::Blocks), BlocksAttrType(t) {}
-
- BlocksAttrTypes getType() const { return BlocksAttrType; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Blocks; }
- static bool classof(const BlocksAttr *A) { return true; }
-};
-
-class FunctionDecl;
-
-class CleanupAttr : public Attr {
- FunctionDecl *FD;
-
-public:
- CleanupAttr(FunctionDecl *fd) : Attr(attr::Cleanup), FD(fd) {}
-
- const FunctionDecl *getFunctionDecl() const { return FD; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Cleanup; }
- static bool classof(const CleanupAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(NoDebug);
-DEF_SIMPLE_ATTR(WarnUnusedResult);
-DEF_SIMPLE_ATTR(NoInline);
-
-class RegparmAttr : public Attr {
- unsigned NumParams;
-
-public:
- RegparmAttr(unsigned np) : Attr(attr::Regparm), NumParams(np) {}
-
- unsigned getNumParams() const { return NumParams; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Regparm; }
- static bool classof(const RegparmAttr *A) { return true; }
-};
-
-class ReqdWorkGroupSizeAttr : public Attr {
- unsigned X, Y, Z;
-public:
- ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
- : Attr(attr::ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
-
- unsigned getXDim() const { return X; }
- unsigned getYDim() const { return Y; }
- unsigned getZDim() const { return Z; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::ReqdWorkGroupSize;
+ friend bool operator!=(specific_attr_iterator Left,
+ specific_attr_iterator Right) {
+ return !(Left == Right);
}
- static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
};
-class InitPriorityAttr : public Attr {
- unsigned Priority;
-public:
- InitPriorityAttr(unsigned priority)
- : Attr(attr::InitPriority), Priority(priority) {}
-
- virtual void Destroy(ASTContext &C) { Attr::Destroy(C); }
-
- unsigned getPriority() const { return Priority; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- static bool classof(const Attr *A)
- { return A->getKind() == attr::InitPriority; }
- static bool classof(const InitPriorityAttr *A) { return true; }
-};
-
-// Checker-specific attributes.
-DEF_SIMPLE_ATTR(CFReturnsNotRetained);
-DEF_SIMPLE_ATTR(CFReturnsRetained);
-DEF_SIMPLE_ATTR(NSReturnsNotRetained);
-DEF_SIMPLE_ATTR(NSReturnsRetained);
-
-// Target-specific attributes
-DEF_SIMPLE_ATTR(DLLImport);
-DEF_SIMPLE_ATTR(DLLExport);
-
-class MSP430InterruptAttr : public Attr {
- unsigned Number;
-
-public:
- MSP430InterruptAttr(unsigned n) : Attr(attr::MSP430Interrupt), Number(n) {}
-
- unsigned getNumber() const { return Number; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A)
- { return A->getKind() == attr::MSP430Interrupt; }
- static bool classof(const MSP430InterruptAttr *A) { return true; }
-};
+template <typename T>
+inline specific_attr_iterator<T> specific_attr_begin(const AttrVec& vec) {
+ return specific_attr_iterator<T>(vec.begin());
+}
+template <typename T>
+inline specific_attr_iterator<T> specific_attr_end(const AttrVec& vec) {
+ return specific_attr_iterator<T>(vec.end());
+}
-DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
+template <typename T>
+inline bool hasSpecificAttr(const AttrVec& vec) {
+ return specific_attr_begin<T>(vec) != specific_attr_end<T>(vec);
+}
+template <typename T>
+inline T *getSpecificAttr(const AttrVec& vec) {
+ specific_attr_iterator<T> i = specific_attr_begin<T>(vec);
+ if (i != specific_attr_end<T>(vec))
+ return *i;
+ else
+ return 0;
+}
-#undef DEF_SIMPLE_ATTR
+/// getMaxAlignment - Returns the highest alignment value found among
+/// AlignedAttrs in an AttrVec, or 0 if there are none.
+inline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) {
+ unsigned Align = 0;
+ specific_attr_iterator<AlignedAttr> i(V.begin()), e(V.end());
+ for(; i != e; ++i)
+ Align = std::max(Align, i->getAlignment(Ctx));
+ return Align;
+}
} // end namespace clang
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index 3b09071..800c583 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -5,6 +5,12 @@ tablegen(Attrs.inc
add_custom_target(ClangAttrClasses
DEPENDS Attrs.inc)
+tablegen(AttrImpl.inc
+ -gen-clang-attr-impl
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrImpl
+ DEPENDS AttrImpl.inc)
+
set(LLVM_TARGET_DEFINITIONS ../Basic/StmtNodes.td)
tablegen(StmtNodes.inc
-gen-clang-stmt-nodes)
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 9f97fd8..dad4dfc 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -273,6 +273,9 @@ public:
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
@@ -700,9 +703,9 @@ inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
template<typename T>
CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
CanQual<T> Result;
- Result.Stored.setFromOpaqueValue(Ptr);
- assert((!Result || Result.Stored.isCanonical())
- && "Type is not canonical!");
+ Result.Stored = QualType::getFromOpaquePtr(Ptr);
+ assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
+ Result.Stored.isCanonical()) && "Type is not canonical!");
return Result;
}
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 39cd51f..6749255 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -118,16 +118,6 @@ public:
return getIdentifier() ? getIdentifier()->getName() : "";
}
- /// getNameAsCString - Get the name of identifier for this declaration as a
- /// C string (const char*). This requires that the declaration have a name
- /// and that it be a simple identifier.
- //
- // FIXME: Deprecated, move clients to getName().
- const char *getNameAsCString() const {
- assert(Name.isIdentifier() && "Name is not a simple identifier");
- return getIdentifier() ? getIdentifier()->getNameStart() : "";
- }
-
/// 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
@@ -229,6 +219,8 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
/// NamespaceDecl - Represent a C++ namespace.
class NamespaceDecl : public NamedDecl, public DeclContext {
+ bool IsInline : 1;
+
SourceLocation LBracLoc, RBracLoc;
// For extended namespace definitions:
@@ -239,7 +231,7 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
// there will be one NamespaceDecl for each declaration.
// NextNamespace points to the next extended declaration.
// OrigNamespace points to the original namespace declaration.
- // OrigNamespace of the first namespace decl points to itself.
+ // OrigNamespace of the first namespace decl points to its anonymous namespace
NamespaceDecl *NextNamespace;
/// \brief A pointer to either the original namespace definition for
@@ -258,28 +250,36 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
NamespaceDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
: NamedDecl(Namespace, DC, L, Id), DeclContext(Namespace),
- NextNamespace(0), OrigOrAnonNamespace(0, true) { }
+ IsInline(false), NextNamespace(0), OrigOrAnonNamespace(0, true) { }
public:
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id);
- virtual void Destroy(ASTContext& C);
-
- // \brief Returns true if this is an anonymous namespace declaration.
- //
- // For example:
+ /// \brief Returns true if this is an anonymous namespace declaration.
+ ///
+ /// For example:
/// \code
- // namespace {
- // ...
- // };
- // \endcode
- // q.v. C++ [namespace.unnamed]
+ /// namespace {
+ /// ...
+ /// };
+ /// \endcode
+ /// q.v. C++ [namespace.unnamed]
bool isAnonymousNamespace() const {
return !getIdentifier();
}
- /// \brief Return the next extended namespace declaration or null if this
+ /// \brief Returns true if this is an inline namespace declaration.
+ bool isInline() const {
+ return IsInline;
+ }
+
+ /// \brief Set whether this is an inline namespace declaration.
+ void setInline(bool Inline) {
+ IsInline = Inline;
+ }
+
+ /// \brief Return the next extended namespace declaration or null if there
/// is none.
NamespaceDecl *getNextNamespace() { return NextNamespace; }
const NamespaceDecl *getNextNamespace() const { return NextNamespace; }
@@ -345,8 +345,8 @@ public:
return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
}
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// ValueDecl - Represent the declaration of a variable (in which case it is
@@ -392,8 +392,6 @@ struct QualifierInfo {
unsigned NumTPLists,
TemplateParameterList **TPLists);
- void Destroy(ASTContext &Context);
-
private:
// Copy constructor and copy assignment are disabled.
QualifierInfo(const QualifierInfo&);
@@ -421,9 +419,6 @@ protected:
: ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo) {}
public:
- virtual ~DeclaratorDecl();
- virtual void Destroy(ASTContext &C);
-
TypeSourceInfo *getTypeSourceInfo() const {
return hasExtInfo()
? getExtInfo()->TInfo
@@ -507,36 +502,11 @@ struct EvaluatedStmt {
APValue Evaluated;
};
-// \brief Describes the kind of template specialization that a
-// particular template specialization declaration represents.
-enum TemplateSpecializationKind {
- /// This template specialization was formed from a template-id but
- /// has not yet been declared, defined, or instantiated.
- TSK_Undeclared = 0,
- /// This template specialization was implicitly instantiated from a
- /// template. (C++ [temp.inst]).
- TSK_ImplicitInstantiation,
- /// This template specialization was declared or defined by an
- /// explicit specialization (C++ [temp.expl.spec]) or partial
- /// specialization (C++ [temp.class.spec]).
- TSK_ExplicitSpecialization,
- /// This template specialization was instantiated from a template
- /// due to an explicit instantiation declaration request
- /// (C++0x [temp.explicit]).
- TSK_ExplicitInstantiationDeclaration,
- /// This template specialization was instantiated from a template
- /// due to an explicit instantiation definition request
- /// (C++ [temp.explicit]).
- TSK_ExplicitInstantiationDefinition
-};
-
/// VarDecl - An instance of this class is created to represent a variable
/// declaration or definition.
class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
public:
- enum StorageClass {
- None, Auto, Register, Extern, Static, PrivateExtern
- };
+ typedef clang::StorageClass StorageClass;
/// getStorageClassSpecifierString - Return the string used to
/// specify the storage class \arg SC.
@@ -568,10 +538,6 @@ private:
bool ThreadSpecified : 1;
bool HasCXXDirectInit : 1;
- /// DeclaredInCondition - Whether this variable was declared in a
- /// condition, e.g., if (int x = foo()) { ... }.
- bool DeclaredInCondition : 1;
-
/// \brief Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
bool ExceptionVar : 1;
@@ -587,7 +553,7 @@ protected:
StorageClass SCAsWritten)
: DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
ThreadSpecified(false), HasCXXDirectInit(false),
- DeclaredInCondition(false), ExceptionVar(false), NRVOVariable(false) {
+ ExceptionVar(false), NRVOVariable(false) {
SClass = SC;
SClassAsWritten = SCAsWritten;
}
@@ -609,9 +575,6 @@ public:
QualType T, TypeSourceInfo *TInfo, StorageClass S,
StorageClass SCAsWritten);
- virtual void Destroy(ASTContext& C);
- virtual ~VarDecl();
-
virtual SourceLocation getInnerLocStart() const;
virtual SourceRange getSourceRange() const;
@@ -619,8 +582,14 @@ public:
StorageClass getStorageClassAsWritten() const {
return (StorageClass) SClassAsWritten;
}
- void setStorageClass(StorageClass SC) { SClass = SC; }
- void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
+ void setStorageClass(StorageClass SC) {
+ assert(isLegalForVariable(SC));
+ SClass = SC;
+ }
+ void setStorageClassAsWritten(StorageClass SC) {
+ assert(isLegalForVariable(SC));
+ SClassAsWritten = SC;
+ }
void setThreadSpecified(bool T) { ThreadSpecified = T; }
bool isThreadSpecified() const {
@@ -630,25 +599,26 @@ public:
/// hasLocalStorage - Returns true if a variable with function scope
/// is a non-static local variable.
bool hasLocalStorage() const {
- if (getStorageClass() == None)
+ if (getStorageClass() == SC_None)
return !isFileVarDecl();
// Return true for: Auto, Register.
// Return false for: Extern, Static, PrivateExtern.
- return getStorageClass() <= Register;
+ return getStorageClass() >= SC_Auto;
}
/// isStaticLocal - Returns true if a variable with function scope is a
/// static local variable.
bool isStaticLocal() const {
- return getStorageClass() == Static && !isFileVarDecl();
+ return getStorageClass() == SC_Static && !isFileVarDecl();
}
/// hasExternStorage - Returns true if a variable has extern or
/// __private_extern__ storage.
bool hasExternalStorage() const {
- return getStorageClass() == Extern || getStorageClass() == PrivateExtern;
+ return getStorageClass() == SC_Extern ||
+ getStorageClass() == SC_PrivateExtern;
}
/// hasGlobalStorage - Returns true for all variables that do not
@@ -670,7 +640,7 @@ public:
if (getKind() != Decl::Var)
return false;
if (const DeclContext *DC = getDeclContext())
- return DC->getLookupContext()->isFunctionOrMethod();
+ return DC->getRedeclContext()->isFunctionOrMethod();
return false;
}
@@ -679,10 +649,8 @@ public:
bool isFunctionOrMethodVarDecl() const {
if (getKind() != Decl::Var)
return false;
- if (const DeclContext *DC = getDeclContext())
- return DC->getLookupContext()->isFunctionOrMethod() &&
- DC->getLookupContext()->getDeclKind() != Decl::Block;
- return false;
+ const DeclContext *DC = getDeclContext()->getRedeclContext();
+ return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
}
/// \brief Determines whether this is a static data member.
@@ -696,7 +664,7 @@ public:
/// \endcode
bool isStaticDataMember() const {
// If it wasn't static, it would be a FieldDecl.
- return getDeclContext()->isRecord();
+ return getKind() != Decl::ParmVar && getDeclContext()->isRecord();
}
virtual VarDecl *getCanonicalDecl();
@@ -743,11 +711,10 @@ public:
bool isFileVarDecl() const {
if (getKind() != Decl::Var)
return false;
- if (const DeclContext *Ctx = getDeclContext()) {
- Ctx = Ctx->getLookupContext();
- if (isa<TranslationUnitDecl>(Ctx) || isa<NamespaceDecl>(Ctx) )
- return true;
- }
+
+ if (getDeclContext()->getRedeclContext()->isFileContext())
+ return true;
+
if (isStaticDataMember())
return true;
@@ -912,18 +879,6 @@ public:
return HasCXXDirectInit;
}
- /// isDeclaredInCondition - Whether this variable was declared as
- /// part of a condition in an if/switch/while statement, e.g.,
- /// @code
- /// if (int x = foo()) { ... }
- /// @endcode
- bool isDeclaredInCondition() const {
- return DeclaredInCondition;
- }
- void setDeclaredInCondition(bool InCondition) {
- DeclaredInCondition = InCondition;
- }
-
/// \brief Determine whether this variable is the exception variable in a
/// C++ catch statememt or an Objective-C @catch statement.
bool isExceptionVariable() const {
@@ -973,7 +928,7 @@ class ImplicitParamDecl : public VarDecl {
protected:
ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType Tw)
- : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, VarDecl::None, VarDecl::None) {}
+ : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, SC_None, SC_None) {}
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
@@ -1117,9 +1072,7 @@ public:
class FunctionDecl : public DeclaratorDecl, public DeclContext,
public Redeclarable<FunctionDecl> {
public:
- enum StorageClass {
- None, Extern, Static, PrivateExtern
- };
+ typedef clang::StorageClass StorageClass;
/// \brief The kind of templated function a FunctionDecl can be.
enum TemplatedKind {
@@ -1179,11 +1132,15 @@ private:
DependentFunctionTemplateSpecializationInfo *>
TemplateOrSpecialization;
+ /// DNLoc - Provides source/type location info for the
+ /// declaration name embedded in the DeclaratorDecl base class.
+ DeclarationNameLoc DNLoc;
+
protected:
- FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ FunctionDecl(Kind DK, DeclContext *DC, const DeclarationNameInfo &NameInfo,
+ QualType T, TypeSourceInfo *TInfo,
StorageClass S, StorageClass SCAsWritten, bool isInline)
- : DeclaratorDecl(DK, DC, L, N, T, TInfo),
+ : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo),
DeclContext(DK),
ParamInfo(0), Body(),
SClass(S), SClassAsWritten(SCAsWritten), IsInline(isInline),
@@ -1191,10 +1148,9 @@ protected:
HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
IsCopyAssignment(false),
HasImplicitReturnZero(false),
- EndRangeLoc(L), TemplateOrSpecialization() {}
-
- virtual ~FunctionDecl() {}
- virtual void Destroy(ASTContext& C);
+ EndRangeLoc(NameInfo.getEndLoc()),
+ TemplateOrSpecialization(),
+ DNLoc(NameInfo.getInfo()) {}
typedef Redeclarable<FunctionDecl> redeclarable_base;
virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
@@ -1211,11 +1167,27 @@ public:
static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName N, QualType T,
TypeSourceInfo *TInfo,
- StorageClass S = None,
- StorageClass SCAsWritten = None,
+ StorageClass S = SC_None,
+ StorageClass SCAsWritten = SC_None,
+ bool isInline = false,
+ bool hasWrittenPrototype = true) {
+ DeclarationNameInfo NameInfo(N, L);
+ return FunctionDecl::Create(C, DC, NameInfo, T, TInfo, S, SCAsWritten,
+ isInline, hasWrittenPrototype);
+ }
+
+ static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
+ const DeclarationNameInfo &NameInfo,
+ QualType T, TypeSourceInfo *TInfo,
+ StorageClass S = SC_None,
+ StorageClass SCAsWritten = SC_None,
bool isInline = false,
bool hasWrittenPrototype = true);
+ DeclarationNameInfo getNameInfo() const {
+ return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
+ }
+
virtual void getNameForDiagnostic(std::string &S,
const PrintingPolicy &Policy,
bool Qualified) const;
@@ -1245,7 +1217,7 @@ public:
/// set that function declaration to the actual declaration
/// containing the body (if there is one).
/// NOTE: For checking if there is a body, use hasBody() instead, to avoid
- /// unnecessary PCH de-serialization of the body.
+ /// unnecessary AST de-serialization of the body.
Stmt *getBody(const FunctionDecl *&Definition) const;
virtual Stmt *getBody() const {
@@ -1389,12 +1361,18 @@ public:
}
StorageClass getStorageClass() const { return StorageClass(SClass); }
- void setStorageClass(StorageClass SC) { SClass = SC; }
+ void setStorageClass(StorageClass SC) {
+ assert(isLegalForFunction(SC));
+ SClass = SC;
+ }
StorageClass getStorageClassAsWritten() const {
return StorageClass(SClassAsWritten);
}
- void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
+ void setStorageClassAsWritten(StorageClass SC) {
+ assert(isLegalForFunction(SC));
+ SClassAsWritten = SC;
+ }
/// \brief Determine whether the "inline" keyword was specified for this
/// function.
@@ -1632,8 +1610,8 @@ public:
return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC));
}
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
@@ -1705,7 +1683,6 @@ protected:
const llvm::APSInt &V)
: ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {}
- virtual ~EnumConstantDecl() {}
public:
static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC,
@@ -1713,8 +1690,6 @@ public:
QualType T, Expr *E,
const llvm::APSInt &V);
- virtual void Destroy(ASTContext& C);
-
const Expr *getInitExpr() const { return (const Expr*) Init; }
Expr *getInitExpr() { return (Expr*) Init; }
const llvm::APSInt &getInitVal() const { return Val; }
@@ -1722,6 +1697,8 @@ public:
void setInitExpr(Expr *E) { Init = (Stmt*) E; }
void setInitVal(const llvm::APSInt &V) { Val = V; }
+ SourceRange getSourceRange() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const EnumConstantDecl *D) { return true; }
@@ -1770,8 +1747,6 @@ class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
IdentifierInfo *Id, TypeSourceInfo *TInfo)
: TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
- virtual ~TypedefDecl();
-
protected:
typedef Redeclarable<TypedefDecl> redeclarable_base;
virtual TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
@@ -1832,6 +1807,9 @@ private:
/// it is a declaration ("struct foo;").
bool IsDefinition : 1;
+ /// IsBeingDefined - True if this is currently being defined.
+ bool IsBeingDefined : 1;
+
/// IsEmbeddedInDeclarator - True if this tag declaration is
/// "embedded" (i.e., defined or declared for the very first time)
/// in the syntax of a declarator.
@@ -1873,6 +1851,7 @@ protected:
"EnumDecl not matched with TTK_Enum");
TagDeclKind = TK;
IsDefinition = false;
+ IsBeingDefined = false;
IsEmbeddedInDeclarator = false;
setPreviousDeclaration(PrevDecl);
}
@@ -1881,8 +1860,6 @@ protected:
virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
public:
- void Destroy(ASTContext &C);
-
typedef redeclarable_base::redecl_iterator redecl_iterator;
redecl_iterator redecls_begin() const {
return redeclarable_base::redecls_begin();
@@ -1911,11 +1888,22 @@ public:
return const_cast<TagDecl*>(this)->getCanonicalDecl();
}
+ /// isThisDeclarationADefinition() - Return true if this declaration
+ /// defines the type. Provided for consistency.
+ bool isThisDeclarationADefinition() const {
+ return isDefinition();
+ }
+
/// isDefinition - Return true if this decl has its body specified.
bool isDefinition() const {
return IsDefinition;
}
+ /// isBeingDefined - Return true if this decl is currently being defined.
+ bool isBeingDefined() const {
+ return IsBeingDefined;
+ }
+
bool isEmbeddedInDeclarator() const {
return IsEmbeddedInDeclarator;
}
@@ -2003,8 +1991,8 @@ public:
return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
}
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
@@ -2037,6 +2025,8 @@ class EnumDecl : public TagDecl {
IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL)
: TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
IntegerType = QualType();
+ NumNegativeBits = 0;
+ NumPositiveBits = 0;
}
public:
EnumDecl *getCanonicalDecl() {
@@ -2058,8 +2048,6 @@ public:
SourceLocation TKL, EnumDecl *PrevDecl);
static EnumDecl *Create(ASTContext &C, EmptyShell Empty);
- virtual void Destroy(ASTContext& C);
-
/// completeDefinition - When created, the EnumDecl corresponds to a
/// forward-declared enum. This method is used to mark the
/// declaration as being defined; it's enumerators have already been
@@ -2167,7 +2155,6 @@ protected:
RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
RecordDecl *PrevDecl, SourceLocation TKL);
- virtual ~RecordDecl();
public:
static RecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
@@ -2183,8 +2170,6 @@ public:
return cast_or_null<RecordDecl>(TagDecl::getPreviousDeclaration());
}
- virtual void Destroy(ASTContext& C);
-
bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
@@ -2307,9 +2292,6 @@ protected:
IsVariadic(false), ParamInfo(0), NumParams(0), Body(0),
SignatureAsWritten(0) {}
- virtual ~BlockDecl();
- virtual void Destroy(ASTContext& C);
-
public:
static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index be30b8e..1369c2b 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -222,11 +222,13 @@ protected:
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
unsigned Access : 2;
friend class CXXClassMemberWrapper;
-
- // PCHLevel - the "level" of precompiled header/AST file from which this
- // declaration was built.
- unsigned PCHLevel : 3;
-
+
+ /// PCHLevel - the "level" of AST file from which this declaration was built.
+ unsigned PCHLevel : 2;
+
+ /// ChangedAfterLoad - if this declaration has changed since being loaded
+ bool ChangedAfterLoad : 1;
+
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
unsigned IdentifierNamespace : 15;
@@ -243,7 +245,7 @@ protected:
: NextDeclInContext(0), DeclCtx(DC),
Loc(L), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false), Used(false),
- Access(AS_none), PCHLevel(0),
+ Access(AS_none), PCHLevel(0), ChangedAfterLoad(false),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
if (Decl::CollectingStats()) add(DK);
}
@@ -251,7 +253,7 @@ protected:
Decl(Kind DK, EmptyShell Empty)
: NextDeclInContext(0), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false), Used(false),
- Access(AS_none), PCHLevel(0),
+ Access(AS_none), PCHLevel(0), ChangedAfterLoad(false),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
if (Decl::CollectingStats()) add(DK);
}
@@ -305,24 +307,52 @@ public:
}
bool hasAttrs() const { return HasAttrs; }
- void initAttrs(Attr *attrs);
- void addAttr(Attr *attr);
- const Attr *getAttrs() const {
- if (!HasAttrs) return 0; // common case, no attributes.
- return getAttrsImpl(); // Uncommon case, out of line hash lookup.
+ void setAttrs(const AttrVec& Attrs);
+ AttrVec& getAttrs() {
+ return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
}
+ const AttrVec &getAttrs() const;
void swapAttrs(Decl *D);
- void invalidateAttrs();
+ void dropAttrs();
+
+ void addAttr(Attr *A) {
+ if (hasAttrs())
+ getAttrs().push_back(A);
+ else
+ setAttrs(AttrVec(1, A));
+ }
+
+ typedef AttrVec::const_iterator attr_iterator;
+
+ // FIXME: Do not rely on iterators having comparable singular values.
+ // Note that this should error out if they do not.
+ attr_iterator attr_begin() const {
+ return hasAttrs() ? getAttrs().begin() : 0;
+ }
+ attr_iterator attr_end() const {
+ return hasAttrs() ? getAttrs().end() : 0;
+ }
- template<typename T> const T *getAttr() const {
- for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
- if (const T *V = dyn_cast<T>(attr))
- return V;
- return 0;
+ template <typename T>
+ specific_attr_iterator<T> specific_attr_begin() const {
+ return specific_attr_iterator<T>(attr_begin());
+ }
+ template <typename T>
+ specific_attr_iterator<T> specific_attr_end() const {
+ return specific_attr_iterator<T>(attr_end());
}
+ template<typename T> T *getAttr() const {
+ return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : 0;
+ }
template<typename T> bool hasAttr() const {
- return getAttr<T>() != 0;
+ return hasAttrs() && hasSpecificAttr<T>(getAttrs());
+ }
+
+ /// getMaxAlignment - return the maximum alignment specified by attributes
+ /// on this decl, 0 if there are none.
+ unsigned getMaxAlignment() const {
+ return hasAttrs() ? getMaxAttrAlignment(getAttrs(), getASTContext()) : 0;
}
/// setInvalidDecl - Indicates the Decl had a semantic error. This
@@ -343,22 +373,21 @@ public:
/// (in addition to the "used" bit set by \c setUsed()) when determining
/// whether the function is used.
bool isUsed(bool CheckUsedAttr = true) const;
-
+
void setUsed(bool U = true) { Used = U; }
/// \brief Retrieve the level of precompiled header from which this
/// declaration was generated.
///
/// The PCH level of a declaration describes where the declaration originated
- /// from. A PCH level of 0 indicates that the declaration was not from a
- /// precompiled header. A PCH level of 1 indicates that the declaration was
- /// from a top-level precompiled header; 2 indicates that the declaration
- /// comes from a precompiled header on which the top-level precompiled header
- /// depends, and so on.
+ /// from. A PCH level of 0 indicates that the declaration was parsed from
+ /// source. A PCH level of 1 indicates that the declaration was loaded from
+ /// a top-level AST file. A PCH level 2 indicates that the declaration was
+ /// loaded from a PCH file the AST file depends on, and so on.
unsigned getPCHLevel() const { return PCHLevel; }
/// \brief The maximum PCH level that any declaration may have.
- static const unsigned MaxPCHLevel = 7;
+ static const unsigned MaxPCHLevel = 3;
/// \brief Set the PCH level of this declaration.
void setPCHLevel(unsigned Level) {
@@ -366,6 +395,19 @@ public:
PCHLevel = Level;
}
+ /// \brief Query whether this declaration was changed in a significant way
+ /// since being loaded from an AST file.
+ ///
+ /// In an epic violation of layering, what is "significant" is entirely
+ /// up to the serialization system, but implemented in AST and Sema.
+ bool isChangedSinceDeserialization() const { return ChangedAfterLoad; }
+
+ /// \brief Mark this declaration as having changed since deserialization, or
+ /// reset the flag.
+ void setChangedSinceDeserialization(bool Changed) {
+ ChangedAfterLoad = Changed;
+ }
+
unsigned getIdentifierNamespace() const {
return IdentifierNamespace;
}
@@ -411,10 +453,10 @@ public:
void setLexicalDeclContext(DeclContext *DC);
- // isDefinedOutsideFunctionOrMethod - This predicate returns true if this
- // scoped decl is defined outside the current function or method. This is
- // roughly global variables and functions, but also handles enums (which could
- // be defined inside or outside a function etc).
+ /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
+ /// scoped decl is defined outside the current function or method. This is
+ /// roughly global variables and functions, but also handles enums (which
+ /// could be defined inside or outside a function etc).
bool isDefinedOutsideFunctionOrMethod() const;
/// \brief Retrieves the "canonical" declaration of the given declaration.
@@ -572,9 +614,6 @@ public:
static DeclContext *castToDeclContext(const Decl *);
static Decl *castFromDeclContext(const DeclContext *);
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
void print(llvm::raw_ostream &Out, unsigned Indentation = 0) const;
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation = 0) const;
@@ -603,6 +642,29 @@ public:
virtual void print(llvm::raw_ostream &OS) const;
};
+class DeclContextLookupResult
+ : public std::pair<NamedDecl**,NamedDecl**> {
+public:
+ DeclContextLookupResult(NamedDecl **I, NamedDecl **E)
+ : std::pair<NamedDecl**,NamedDecl**>(I, E) {}
+ DeclContextLookupResult()
+ : std::pair<NamedDecl**,NamedDecl**>() {}
+
+ using std::pair<NamedDecl**,NamedDecl**>::operator=;
+};
+
+class DeclContextLookupConstResult
+ : public std::pair<NamedDecl*const*, NamedDecl*const*> {
+public:
+ DeclContextLookupConstResult(std::pair<NamedDecl**,NamedDecl**> R)
+ : std::pair<NamedDecl*const*, NamedDecl*const*>(R) {}
+ DeclContextLookupConstResult(NamedDecl * const *I, NamedDecl * const *E)
+ : std::pair<NamedDecl*const*, NamedDecl*const*>(I, E) {}
+ DeclContextLookupConstResult()
+ : std::pair<NamedDecl*const*, NamedDecl*const*>() {}
+
+ using std::pair<NamedDecl*const*,NamedDecl*const*>::operator=;
+};
/// DeclContext - This is used only as base class of specific decl types that
/// can act as declaration contexts. These decls are (only the top classes
@@ -654,8 +716,6 @@ protected:
ExternalVisibleStorage(false), LookupPtr(0), FirstDecl(0),
LastDecl(0) { }
- void DestroyDecls(ASTContext &C);
-
public:
~DeclContext();
@@ -724,6 +784,8 @@ public:
return DeclKind == Decl::Namespace;
}
+ bool isInlineNamespace() const;
+
/// \brief Determines whether this context is dependent on a
/// template parameter.
bool isDependentContext() const;
@@ -742,19 +804,18 @@ public:
/// Here, E is a transparent context, so its enumerator (Val1) will
/// appear (semantically) that it is in the same context of E.
/// Examples of transparent contexts include: enumerations (except for
- /// C++0x scoped enums), C++ linkage specifications, and C++0x
- /// inline namespaces.
+ /// C++0x scoped enums), and C++ linkage specifications.
bool isTransparentContext() const;
/// \brief Determine whether this declaration context is equivalent
/// to the declaration context DC.
- bool Equals(DeclContext *DC) {
+ bool Equals(const DeclContext *DC) const {
return DC && this->getPrimaryContext() == DC->getPrimaryContext();
}
/// \brief Determine whether this declaration context encloses the
/// declaration context DC.
- bool Encloses(DeclContext *DC);
+ bool Encloses(const DeclContext *DC) const;
/// getPrimaryContext - There may be many different
/// declarations of the same entity (including forward declarations
@@ -767,13 +828,12 @@ public:
return const_cast<DeclContext*>(this)->getPrimaryContext();
}
- /// getLookupContext - Retrieve the innermost non-transparent
- /// context of this context, which corresponds to the innermost
- /// location from which name lookup can find the entities in this
- /// context.
- DeclContext *getLookupContext();
- const DeclContext *getLookupContext() const {
- return const_cast<DeclContext *>(this)->getLookupContext();
+ /// getRedeclContext - Retrieve the context in which an entity conflicts with
+ /// other entities of the same name, or where it is a redeclaration if the
+ /// two entities are compatible. This skips through transparent contexts.
+ DeclContext *getRedeclContext();
+ const DeclContext *getRedeclContext() const {
+ return const_cast<DeclContext *>(this)->getRedeclContext();
}
/// \brief Retrieve the nearest enclosing namespace context.
@@ -782,6 +842,14 @@ public:
return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
}
+ /// \brief Test if this context is part of the enclosing namespace set of
+ /// the context NS, as defined in C++0x [namespace.def]p9. If either context
+ /// isn't a namespace, this is equivalent to Equals().
+ ///
+ /// The enclosing namespace set of a namespace is the namespace and, if it is
+ /// inline, its enclosing namespace, recursively.
+ bool InEnclosingNamespaceSetOf(const DeclContext *NS) const;
+
/// getNextContext - If this is a DeclContext that may have other
/// DeclContexts that are semantically connected but syntactically
/// different, such as C++ namespaces, this routine retrieves the
@@ -845,6 +913,12 @@ public:
decl_iterator decls_end() const;
bool decls_empty() const;
+ /// noload_decls_begin/end - Iterate over the declarations stored in this
+ /// context that are currently loaded; don't attempt to retrieve anything
+ /// from an external source.
+ decl_iterator noload_decls_begin() const;
+ decl_iterator noload_decls_end() const;
+
/// specific_decl_iterator - Iterates over a subrange of
/// declarations stored in a DeclContext, providing only those that
/// are of type SpecificDecl (or a class derived from it). This
@@ -1020,9 +1094,8 @@ public:
/// access to the results of lookup up a name within this context.
typedef NamedDecl * const * lookup_const_iterator;
- typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
- typedef std::pair<lookup_const_iterator, lookup_const_iterator>
- lookup_const_result;
+ typedef DeclContextLookupResult lookup_result;
+ typedef DeclContextLookupConstResult lookup_const_result;
/// lookup - Find the declarations (if any) with the given Name in
/// this context. Returns a range of iterators that contains all of
@@ -1052,6 +1125,14 @@ public:
/// the declaration chains.
void makeDeclVisibleInContext(NamedDecl *D, bool Recoverable = true);
+ /// \brief Deserialize all the visible declarations from external storage.
+ ///
+ /// Name lookup deserializes visible declarations lazily, thus a DeclContext
+ /// 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.
+ void MaterializeVisibleDeclsFromExternalStorage();
+
/// udir_iterator - Iterates through the using-directives stored
/// within this context.
typedef UsingDirectiveDecl * const * udir_iterator;
@@ -1109,7 +1190,6 @@ public:
private:
void LoadLexicalDeclsFromExternalStorage() const;
- void LoadVisibleDeclsFromExternalStorage() const;
friend class DependentDiagnostic;
StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
@@ -1123,7 +1203,6 @@ inline bool Decl::isTemplateParameter() const {
getKind() == TemplateTemplateParm;
}
-
// Specialization selected when ToTy is not a known subclass of DeclContext.
template <class ToTy,
bool IsKnownSubtype = ::llvm::is_base_of< DeclContext, ToTy>::value>
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 41474ab..a9802bf 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -17,6 +17,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/TypeLoc.h"
#include "clang/AST/UnresolvedSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -159,7 +160,6 @@ class CXXBaseSpecifier {
/// Range - The source code range that covers the full base
/// specifier, including the "virtual" (if present) and access
/// specifier (if present).
- // FIXME: Move over to a TypeLoc!
SourceRange Range;
/// Virtual - Whether this is a virtual base class or not.
@@ -177,15 +177,17 @@ class CXXBaseSpecifier {
/// VC++ bug.
unsigned Access : 2;
- /// BaseType - The type of the base class. This will be a class or
- /// struct (or a typedef of such).
- QualType BaseType;
+ /// BaseTypeInfo - The type of the base class. This will be a class or struct
+ /// (or a typedef of such). The source code range does not include the
+ /// "virtual" or access specifier.
+ TypeSourceInfo *BaseTypeInfo;
public:
CXXBaseSpecifier() { }
- CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, QualType T)
- : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseType(T) { }
+ CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A,
+ TypeSourceInfo *TInfo)
+ : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseTypeInfo(TInfo) { }
/// getSourceRange - Retrieves the source range that contains the
/// entire base specifier.
@@ -195,7 +197,7 @@ public:
/// class (or not).
bool isVirtual() const { return Virtual; }
- /// \brief Determine whether this base class if a base of a class declared
+ /// \brief Determine whether this base class is a base of a class declared
/// with the 'class' keyword (vs. one declared with the 'struct' keyword).
bool isBaseOfClass() const { return BaseOfClass; }
@@ -221,7 +223,10 @@ public:
/// getType - Retrieves the type of the base class. This type will
/// always be an unqualified class type.
- QualType getType() const { return BaseType; }
+ QualType getType() const { return BaseTypeInfo->getType(); }
+
+ /// getTypeLoc - Retrieves the type and source location of the base class.
+ TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
};
/// CXXRecordDecl - Represents a C++ struct/union/class.
@@ -400,8 +405,6 @@ protected:
CXXRecordDecl *PrevDecl,
SourceLocation TKL = SourceLocation());
- ~CXXRecordDecl();
-
public:
/// base_class_iterator - Iterator that traverses the base classes
/// of a class.
@@ -449,8 +452,6 @@ public:
bool DelayTypeCreation = false);
static CXXRecordDecl *Create(ASTContext &C, EmptyShell Empty);
- virtual void Destroy(ASTContext& C);
-
bool isDynamicClass() const {
return data().Polymorphic || data().NumVBases != 0;
}
@@ -1056,29 +1057,30 @@ public:
return true;
}
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// CXXMethodDecl - Represents a static or instance method of a
/// struct/union/class.
class CXXMethodDecl : public FunctionDecl {
protected:
- CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L,
- DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ CXXMethodDecl(Kind DK, CXXRecordDecl *RD,
+ const DeclarationNameInfo &NameInfo,
+ QualType T, TypeSourceInfo *TInfo,
bool isStatic, StorageClass SCAsWritten, bool isInline)
- : FunctionDecl(DK, RD, L, N, T, TInfo, (isStatic ? Static : None),
+ : FunctionDecl(DK, RD, NameInfo, T, TInfo, (isStatic ? SC_Static : SC_None),
SCAsWritten, isInline) {}
public:
static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, DeclarationName N,
- QualType T, TypeSourceInfo *TInfo,
- bool isStatic = false,
- StorageClass SCAsWritten = FunctionDecl::None,
- bool isInline = false);
+ const DeclarationNameInfo &NameInfo,
+ QualType T, TypeSourceInfo *TInfo,
+ bool isStatic = false,
+ StorageClass SCAsWritten = SC_None,
+ bool isInline = false);
- bool isStatic() const { return getStorageClass() == Static; }
+ bool isStatic() const { return getStorageClass() == SC_Static; }
bool isInstance() const { return !isStatic(); }
bool isVirtual() const {
@@ -1249,9 +1251,6 @@ public:
VarDecl **Indices,
unsigned NumIndices);
- /// \brief Destroy the base or member initializer.
- void Destroy(ASTContext &Context);
-
/// isBaseInitializer - Returns true when this initializer is
/// initializing a base class.
bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); }
@@ -1285,7 +1284,7 @@ public:
/// getMember - If this is a member initializer, returns the
/// declaration of the non-static data member being
/// initialized. Otherwise, returns NULL.
- FieldDecl *getMember() {
+ FieldDecl *getMember() const {
if (isMemberInitializer())
return BaseOrMember.get<FieldDecl*>();
else
@@ -1363,7 +1362,7 @@ public:
reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
}
- Expr *getInit() { return static_cast<Expr *>(Init); }
+ Expr *getInit() const { return static_cast<Expr *>(Init); }
};
/// CXXConstructorDecl - Represents a C++ constructor within a
@@ -1394,22 +1393,21 @@ class CXXConstructorDecl : public CXXMethodDecl {
CXXBaseOrMemberInitializer **BaseOrMemberInitializers;
unsigned NumBaseOrMemberInitializers;
- CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
- DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ CXXConstructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
+ QualType T, TypeSourceInfo *TInfo,
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false,
- FunctionDecl::None, isInline),
+ : CXXMethodDecl(CXXConstructor, RD, NameInfo, T, TInfo, false,
+ SC_None, isInline),
IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
- virtual void Destroy(ASTContext& C);
public:
static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, DeclarationName N,
+ const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isExplicit,
bool isInline, bool isImplicitlyDeclared);
@@ -1519,8 +1517,8 @@ public:
static bool classof(const CXXConstructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConstructor; }
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// CXXDestructorDecl - Represents a C++ destructor within a
@@ -1543,11 +1541,10 @@ class CXXDestructorDecl : public CXXMethodDecl {
FunctionDecl *OperatorDelete;
- CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
- DeclarationName N, QualType T,
- bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*TInfo=*/0, false,
- FunctionDecl::None, isInline),
+ CXXDestructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
+ QualType T, bool isInline, bool isImplicitlyDeclared)
+ : CXXMethodDecl(CXXDestructor, RD, NameInfo, T, /*TInfo=*/0, false,
+ SC_None, isInline),
ImplicitlyDefined(false), OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -1555,7 +1552,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
public:
static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, DeclarationName N,
+ const DeclarationNameInfo &NameInfo,
QualType T, bool isInline,
bool isImplicitlyDeclared);
@@ -1585,8 +1582,8 @@ public:
static bool classof(const CXXDestructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXDestructor; }
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// CXXConversionDecl - Represents a C++ conversion function within a
@@ -1604,17 +1601,17 @@ class CXXConversionDecl : public CXXMethodDecl {
/// explicitly wrote a cast. This is a C++0x feature.
bool IsExplicitSpecified : 1;
- CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
- DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ CXXConversionDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
+ QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicitSpecified)
- : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false,
- FunctionDecl::None, isInline),
+ : CXXMethodDecl(CXXConversion, RD, NameInfo, T, TInfo, false,
+ SC_None, isInline),
IsExplicitSpecified(isExplicitSpecified) { }
public:
static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, DeclarationName N,
+ const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicit);
@@ -1642,8 +1639,8 @@ public:
static bool classof(const CXXConversionDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConversion; }
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// LinkageSpecDecl - This represents a linkage specification. For example:
@@ -1710,7 +1707,9 @@ public:
// artificial name, for all using-directives in order to store
// them in DeclContext effectively.
class UsingDirectiveDecl : public NamedDecl {
-
+ /// \brief The location of the "using" keyword.
+ SourceLocation UsingLoc;
+
/// SourceLocation - Location of 'namespace' token.
SourceLocation NamespaceLoc;
@@ -1722,10 +1721,6 @@ class UsingDirectiveDecl : public NamedDecl {
/// name, if any.
NestedNameSpecifier *Qualifier;
- /// IdentLoc - Location of nominated namespace-name identifier.
- // FIXME: We don't store location of scope specifier.
- SourceLocation IdentLoc;
-
/// NominatedNamespace - Namespace nominated by using-directive.
NamedDecl *NominatedNamespace;
@@ -1740,17 +1735,16 @@ class UsingDirectiveDecl : public NamedDecl {
return DeclarationName::getUsingDirectiveName();
}
- UsingDirectiveDecl(DeclContext *DC, SourceLocation L,
+ UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc,
SourceLocation NamespcLoc,
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc,
NamedDecl *Nominated,
DeclContext *CommonAncestor)
- : NamedDecl(UsingDirective, DC, L, getName()),
+ : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc),
NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange),
- Qualifier(Qualifier), IdentLoc(IdentLoc),
- NominatedNamespace(Nominated),
+ Qualifier(Qualifier), NominatedNamespace(Nominated),
CommonAncestor(CommonAncestor) {
}
@@ -1759,18 +1753,10 @@ public:
/// that qualifies the namespace name.
SourceRange getQualifierRange() const { return QualifierRange; }
- /// \brief Set the source range of the nested-name-specifier that
- /// qualifies the namespace name.
- void setQualifierRange(SourceRange R) { QualifierRange = R; }
-
/// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
- /// \brief Set the nested-name-specifier that qualifes the name of the
- /// namespace.
- void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
-
NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
const NamedDecl *getNominatedNamespaceAsWritten() const {
return NominatedNamespace;
@@ -1783,34 +1769,23 @@ public:
return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
}
- /// setNominatedNamespace - Set the namespace nominataed by the
- /// using-directive.
- void setNominatedNamespace(NamedDecl* NS);
-
/// \brief Returns the common ancestor context of this using-directive and
/// its nominated namespace.
DeclContext *getCommonAncestor() { return CommonAncestor; }
const DeclContext *getCommonAncestor() const { return CommonAncestor; }
- /// \brief Set the common ancestor context of this using-directive and its
- /// nominated namespace.
- void setCommonAncestor(DeclContext* Cxt) { CommonAncestor = Cxt; }
-
+ /// \brief Return the location of the "using" keyword.
+ SourceLocation getUsingLoc() const { return UsingLoc; }
+
// FIXME: Could omit 'Key' in name.
/// getNamespaceKeyLocation - Returns location of namespace keyword.
SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
- /// setNamespaceKeyLocation - Set the the location of the namespacekeyword.
- void setNamespaceKeyLocation(SourceLocation L) { NamespaceLoc = L; }
-
/// getIdentLocation - Returns location of identifier.
- SourceLocation getIdentLocation() const { return IdentLoc; }
-
- /// setIdentLocation - set the location of the identifier.
- void setIdentLocation(SourceLocation L) { IdentLoc = L; }
+ SourceLocation getIdentLocation() const { return getLocation(); }
static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
+ SourceLocation UsingLoc,
SourceLocation NamespaceLoc,
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
@@ -1818,12 +1793,18 @@ public:
NamedDecl *Nominated,
DeclContext *CommonAncestor);
+ SourceRange getSourceRange() const {
+ return SourceRange(UsingLoc, getLocation());
+ }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingDirectiveDecl *D) { return true; }
static bool classofKind(Kind K) { return K == UsingDirective; }
// Friend for getUsingDirectiveName.
friend class DeclContext;
+
+ friend class ASTDeclReader;
};
/// NamespaceAliasDecl - Represents a C++ namespace alias. For example:
@@ -1832,7 +1813,8 @@ public:
/// namespace Foo = Bar;
/// @endcode
class NamespaceAliasDecl : public NamedDecl {
- SourceLocation AliasLoc;
+ /// \brief The location of the "namespace" keyword.
+ SourceLocation NamespaceLoc;
/// \brief The source range that covers the nested-name-specifier
/// preceding the namespace name.
@@ -1849,15 +1831,17 @@ class NamespaceAliasDecl : public NamedDecl {
/// NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *Namespace;
- NamespaceAliasDecl(DeclContext *DC, SourceLocation L,
+ NamespaceAliasDecl(DeclContext *DC, SourceLocation NamespaceLoc,
SourceLocation AliasLoc, IdentifierInfo *Alias,
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc, NamedDecl *Namespace)
- : NamedDecl(NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc),
- QualifierRange(QualifierRange), Qualifier(Qualifier),
- IdentLoc(IdentLoc), Namespace(Namespace) { }
+ : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias),
+ NamespaceLoc(NamespaceLoc), QualifierRange(QualifierRange),
+ Qualifier(Qualifier), IdentLoc(IdentLoc), Namespace(Namespace) { }
+ friend class ASTDeclReader;
+
public:
/// \brief Retrieve the source range of the nested-name-specifier
/// that qualifiers the namespace name.
@@ -1889,41 +1873,31 @@ public:
/// Returns the location of the alias name, i.e. 'foo' in
/// "namespace foo = ns::bar;".
- SourceLocation getAliasLoc() const { return AliasLoc; }
-
- /// Set the location o;f the alias name, e.e., 'foo' in
- /// "namespace foo = ns::bar;".
- void setAliasLoc(SourceLocation L) { AliasLoc = L; }
+ SourceLocation getAliasLoc() const { return getLocation(); }
/// Returns the location of the 'namespace' keyword.
- SourceLocation getNamespaceLoc() const { return getLocation(); }
+ SourceLocation getNamespaceLoc() const { return NamespaceLoc; }
/// Returns the location of the identifier in the named namespace.
SourceLocation getTargetNameLoc() const { return IdentLoc; }
- /// Set the location of the identifier in the named namespace.
- void setTargetNameLoc(SourceLocation L) { IdentLoc = L; }
-
/// \brief Retrieve the namespace that this alias refers to, which
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *getAliasedNamespace() const { return Namespace; }
- /// \brief Set the namespace or namespace alias pointed to by this
- /// alias decl.
- void setAliasedNamespace(NamedDecl *ND) {
- assert((isa<NamespaceAliasDecl>(ND) || isa<NamespaceDecl>(ND)) &&
- "expecting namespace or namespace alias decl");
- Namespace = ND;
- }
-
static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, SourceLocation AliasLoc,
+ SourceLocation NamespaceLoc,
+ SourceLocation AliasLoc,
IdentifierInfo *Alias,
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc,
NamedDecl *Namespace);
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(NamespaceLoc, IdentLoc);
+ }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamespaceAliasDecl *D) { return true; }
static bool classofKind(Kind K) { return K == NamespaceAlias; }
@@ -2002,6 +1976,10 @@ class UsingDecl : public NamedDecl {
/// \brief Target nested name specifier.
NestedNameSpecifier* TargetNestedName;
+ /// DNLoc - Provides source/type location info for the
+ /// declaration name embedded in the ValueDecl base class.
+ DeclarationNameLoc DNLoc;
+
/// \brief The collection of shadow declarations associated with
/// this using declaration. This set can change as a class is
/// processed.
@@ -2010,34 +1988,31 @@ class UsingDecl : public NamedDecl {
// \brief Has 'typename' keyword.
bool IsTypeName;
- UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
+ UsingDecl(DeclContext *DC, SourceRange NNR,
SourceLocation UL, NestedNameSpecifier* TargetNNS,
- DeclarationName Name, bool IsTypeNameArg)
- : NamedDecl(Using, DC, L, Name),
+ const DeclarationNameInfo &NameInfo, bool IsTypeNameArg)
+ : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
- IsTypeName(IsTypeNameArg) {
+ DNLoc(NameInfo.getInfo()), IsTypeName(IsTypeNameArg) {
}
public:
- // FIXME: Should be const?
/// \brief Returns the source range that covers the nested-name-specifier
/// preceding the namespace name.
- SourceRange getNestedNameRange() { return NestedNameRange; }
+ SourceRange getNestedNameRange() const { return NestedNameRange; }
/// \brief Set the source range of the nested-name-specifier.
void setNestedNameRange(SourceRange R) { NestedNameRange = R; }
- // FIXME; Should be const?
// FIXME: Naming is inconsistent with other get*Loc functions.
/// \brief Returns the source location of the "using" keyword.
- SourceLocation getUsingLocation() { return UsingLocation; }
+ SourceLocation getUsingLocation() const { return UsingLocation; }
/// \brief Set the source location of the 'using' keyword.
void setUsingLocation(SourceLocation L) { UsingLocation = L; }
-
/// \brief Get the target nested name declaration.
- NestedNameSpecifier* getTargetNestedNameDecl() {
+ NestedNameSpecifier* getTargetNestedNameDecl() const {
return TargetNestedName;
}
@@ -2046,6 +2021,10 @@ public:
TargetNestedName = NNS;
}
+ DeclarationNameInfo getNameInfo() const {
+ return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
+ }
+
/// \brief Return true if the using declaration has 'typename'.
bool isTypeName() const { return IsTypeName; }
@@ -2076,15 +2055,21 @@ public:
}
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
- NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
+ SourceRange NNR, SourceLocation UsingL,
+ NestedNameSpecifier* TargetNNS,
+ const DeclarationNameInfo &NameInfo,
+ bool IsTypeNameArg);
+
+ SourceRange getSourceRange() const {
+ return SourceRange(UsingLocation, getNameInfo().getEndLoc());
+ }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Using; }
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// UnresolvedUsingValueDecl - Represents a dependent using
@@ -2105,14 +2090,18 @@ class UnresolvedUsingValueDecl : public ValueDecl {
NestedNameSpecifier *TargetNestedNameSpecifier;
+ /// DNLoc - Provides source/type location info for the
+ /// declaration name embedded in the ValueDecl base class.
+ DeclarationNameLoc DNLoc;
+
UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
SourceLocation UsingLoc, SourceRange TargetNNR,
NestedNameSpecifier *TargetNNS,
- SourceLocation TargetNameLoc,
- DeclarationName TargetName)
- : ValueDecl(UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
- TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
- TargetNestedNameSpecifier(TargetNNS)
+ const DeclarationNameInfo &NameInfo)
+ : ValueDecl(UnresolvedUsingValue, DC,
+ NameInfo.getLoc(), NameInfo.getName(), Ty),
+ TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+ TargetNestedNameSpecifier(TargetNNS), DNLoc(NameInfo.getInfo())
{ }
public:
@@ -2125,7 +2114,7 @@ public:
void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
/// \brief Get target nested name declaration.
- NestedNameSpecifier* getTargetNestedNameSpecifier() {
+ NestedNameSpecifier* getTargetNestedNameSpecifier() const {
return TargetNestedNameSpecifier;
}
@@ -2140,10 +2129,18 @@ public:
/// \brief Set the source location of the 'using' keyword.
void setUsingLoc(SourceLocation L) { UsingLocation = L; }
+ DeclarationNameInfo getNameInfo() const {
+ return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
+ }
+
static UnresolvedUsingValueDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
- SourceLocation TargetNameLoc, DeclarationName TargetName);
+ const DeclarationNameInfo &NameInfo);
+
+ SourceRange getSourceRange() const {
+ return SourceRange(UsingLocation, getNameInfo().getEndLoc());
+ }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
@@ -2181,43 +2178,34 @@ class UnresolvedUsingTypenameDecl : public TypeDecl {
TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
{ }
+ friend class ASTDeclReader;
+
public:
/// \brief Returns the source range that covers the nested-name-specifier
/// preceding the namespace name.
SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
- /// \brief Set the source range coverting the nested-name-specifier preceding
- /// the namespace name.
- void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
-
/// \brief Get target nested name declaration.
NestedNameSpecifier* getTargetNestedNameSpecifier() {
return TargetNestedNameSpecifier;
}
- /// \brief Set the nested name declaration.
- void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
- TargetNestedNameSpecifier = NNS;
- }
-
/// \brief Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
- /// \brief Set the source location of the 'using' keyword.
- void setUsingLoc(SourceLocation L) { UsingLocation = L; }
-
/// \brief Returns the source location of the 'typename' keyword.
SourceLocation getTypenameLoc() const { return TypenameLocation; }
- /// \brief Set the source location of the 'typename' keyword.
- void setTypenameLoc(SourceLocation L) { TypenameLocation = L; }
-
static UnresolvedUsingTypenameDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceLocation TypenameLoc,
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
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; }
@@ -2243,12 +2231,11 @@ public:
StringLiteral *getMessage() { return Message; }
const StringLiteral *getMessage() const { return Message; }
- virtual ~StaticAssertDecl();
- virtual void Destroy(ASTContext& C);
-
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; }
+
+ friend class ASTDeclReader;
};
/// Insertion operator for diagnostics. This allows sending AccessSpecifier's
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 9602b67..97da6ca 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -29,108 +29,54 @@ class DependentDiagnostic;
/// StoredDeclsList - This is an array of decls optimized a common case of only
/// containing one entry.
struct StoredDeclsList {
- /// The kind of data encoded in this list.
- enum DataKind {
- /// \brief The data is a NamedDecl*.
- DK_Decl = 0,
- /// \brief The data is a declaration ID (an unsigned value),
- /// shifted left by 2 bits.
- DK_DeclID = 1,
- /// \brief The data is a pointer to a vector (of type VectorTy)
- /// that contains declarations.
- DK_Decl_Vector = 2,
- /// \brief The data is a pointer to a vector (of type VectorTy)
- /// that contains declaration ID.
- DK_ID_Vector = 3
- };
-
- /// VectorTy - When in vector form, this is what the Data pointer points to.
- typedef llvm::SmallVector<uintptr_t, 4> VectorTy;
-
- /// \brief The stored data, which will be either a declaration ID, a
- /// pointer to a NamedDecl, or a pointer to a vector.
- uintptr_t Data;
+
+ /// DeclsTy - When in vector form, this is what the Data pointer points to.
+ typedef llvm::SmallVector<NamedDecl *, 4> DeclsTy;
+
+ /// \brief The stored data, which will be either a pointer to a NamedDecl,
+ /// or a pointer to a vector.
+ llvm::PointerUnion<NamedDecl *, DeclsTy *> Data;
public:
- StoredDeclsList() : Data(0) {}
+ StoredDeclsList() {}
StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
- if (VectorTy *RHSVec = RHS.getAsVector()) {
- VectorTy *New = new VectorTy(*RHSVec);
- Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03);
- }
+ if (DeclsTy *RHSVec = RHS.getAsVector())
+ Data = new DeclsTy(*RHSVec);
}
~StoredDeclsList() {
// If this is a vector-form, free the vector.
- if (VectorTy *Vector = getAsVector())
+ if (DeclsTy *Vector = getAsVector())
delete Vector;
}
StoredDeclsList &operator=(const StoredDeclsList &RHS) {
- if (VectorTy *Vector = getAsVector())
+ if (DeclsTy *Vector = getAsVector())
delete Vector;
Data = RHS.Data;
- if (VectorTy *RHSVec = RHS.getAsVector()) {
- VectorTy *New = new VectorTy(*RHSVec);
- Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03);
- }
+ if (DeclsTy *RHSVec = RHS.getAsVector())
+ Data = new DeclsTy(*RHSVec);
return *this;
}
- bool isNull() const { return (Data & ~0x03) == 0; }
+ bool isNull() const { return Data.isNull(); }
NamedDecl *getAsDecl() const {
- if ((Data & 0x03) != DK_Decl)
- return 0;
-
- return reinterpret_cast<NamedDecl *>(Data & ~0x03);
+ return Data.dyn_cast<NamedDecl *>();
}
- VectorTy *getAsVector() const {
- if ((Data & 0x03) != DK_ID_Vector && (Data & 0x03) != DK_Decl_Vector)
- return 0;
-
- return reinterpret_cast<VectorTy *>(Data & ~0x03);
+ DeclsTy *getAsVector() const {
+ return Data.dyn_cast<DeclsTy *>();
}
void setOnlyValue(NamedDecl *ND) {
assert(!getAsVector() && "Not inline");
- Data = reinterpret_cast<uintptr_t>(ND);
- }
-
- void setFromDeclIDs(const llvm::SmallVectorImpl<unsigned> &Vec) {
- if (Vec.size() > 1) {
- VectorTy *Vector = getAsVector();
- if (!Vector) {
- Vector = new VectorTy;
- Data = reinterpret_cast<uintptr_t>(Vector) | DK_ID_Vector;
- }
-
- Vector->resize(Vec.size());
- std::copy(Vec.begin(), Vec.end(), Vector->begin());
- return;
- }
-
- if (VectorTy *Vector = getAsVector())
- delete Vector;
-
- if (Vec.empty())
- Data = 0;
- else
- Data = (Vec[0] << 2) | DK_DeclID;
- }
-
- /// \brief Force the stored declarations list to contain actual
- /// declarations.
- ///
- /// This routine will resolve any declaration IDs for declarations
- /// that may not yet have been loaded from external storage.
- void materializeDecls(ASTContext &Context);
-
- bool hasDeclarationIDs() const {
- DataKind DK = (DataKind)(Data & 0x03);
- return DK == DK_DeclID || DK == DK_ID_Vector;
+ Data = ND;
+ // Make sure that Data is a plain NamedDecl* so we can use its address
+ // at getLookupResult.
+ assert(*(NamedDecl **)&Data == ND &&
+ "PointerUnion mangles the NamedDecl pointer!");
}
void remove(NamedDecl *D) {
@@ -138,30 +84,26 @@ public:
if (NamedDecl *Singleton = getAsDecl()) {
assert(Singleton == D && "list is different singleton");
(void)Singleton;
- Data = 0;
+ Data = (NamedDecl *)0;
return;
}
- VectorTy &Vec = *getAsVector();
- VectorTy::iterator I = std::find(Vec.begin(), Vec.end(),
- reinterpret_cast<uintptr_t>(D));
+ DeclsTy &Vec = *getAsVector();
+ DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D);
assert(I != Vec.end() && "list does not contain decl");
Vec.erase(I);
- assert(std::find(Vec.begin(), Vec.end(), reinterpret_cast<uintptr_t>(D))
+ assert(std::find(Vec.begin(), Vec.end(), D)
== Vec.end() && "list still contains decl");
}
/// getLookupResult - Return an array of all the decls that this list
/// represents.
- DeclContext::lookup_result getLookupResult(ASTContext &Context) {
+ DeclContext::lookup_result getLookupResult() {
if (isNull())
return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
DeclContext::lookup_iterator(0));
- if (hasDeclarationIDs())
- materializeDecls(Context);
-
// If we have a single NamedDecl, return it.
if (getAsDecl()) {
assert(!isNull() && "Empty list isn't allowed");
@@ -172,19 +114,15 @@ public:
}
assert(getAsVector() && "Must have a vector at this point");
- VectorTy &Vector = *getAsVector();
+ DeclsTy &Vector = *getAsVector();
// Otherwise, we have a range result.
- return DeclContext::lookup_result((NamedDecl **)&Vector[0],
- (NamedDecl **)&Vector[0]+Vector.size());
+ return DeclContext::lookup_result(&Vector[0], &Vector[0]+Vector.size());
}
/// HandleRedeclaration - If this is a redeclaration of an existing decl,
/// replace the old one with D and return true. Otherwise return false.
- bool HandleRedeclaration(ASTContext &Context, NamedDecl *D) {
- if (hasDeclarationIDs())
- materializeDecls(Context);
-
+ bool HandleRedeclaration(NamedDecl *D) {
// Most decls only have one entry in their list, special case it.
if (NamedDecl *OldD = getAsDecl()) {
if (!D->declarationReplaces(OldD))
@@ -194,12 +132,12 @@ public:
}
// Determine if this declaration is actually a redeclaration.
- VectorTy &Vec = *getAsVector();
- for (VectorTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
+ DeclsTy &Vec = *getAsVector();
+ for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
OD != ODEnd; ++OD) {
- NamedDecl *OldD = reinterpret_cast<NamedDecl *>(*OD);
+ NamedDecl *OldD = *OD;
if (D->declarationReplaces(OldD)) {
- *OD = reinterpret_cast<uintptr_t>(D);
+ *OD = D;
return true;
}
}
@@ -211,17 +149,15 @@ public:
/// not a redeclaration to merge it into the appropriate place in our list.
///
void AddSubsequentDecl(NamedDecl *D) {
- assert(!hasDeclarationIDs() && "Must materialize before adding decls");
-
// If this is the second decl added to the list, convert this to vector
// form.
if (NamedDecl *OldD = getAsDecl()) {
- VectorTy *VT = new VectorTy();
- VT->push_back(reinterpret_cast<uintptr_t>(OldD));
- Data = reinterpret_cast<uintptr_t>(VT) | DK_Decl_Vector;
+ DeclsTy *VT = new DeclsTy();
+ VT->push_back(OldD);
+ Data = VT;
}
- VectorTy &Vec = *getAsVector();
+ DeclsTy &Vec = *getAsVector();
// Using directives end up in a special entry which contains only
// other using directives, so all this logic is wasted for them.
@@ -232,32 +168,30 @@ public:
// iterator which points at the first tag will start a span of
// decls that only contains tags.
if (D->hasTagIdentifierNamespace())
- Vec.push_back(reinterpret_cast<uintptr_t>(D));
+ Vec.push_back(D);
// Resolved using declarations go at the front of the list so that
// they won't show up in other lookup results. Unresolved using
// declarations (which are always in IDNS_Using | IDNS_Ordinary)
// follow that so that the using declarations will be contiguous.
else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
- VectorTy::iterator I = Vec.begin();
+ DeclsTy::iterator I = Vec.begin();
if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
while (I != Vec.end() &&
- reinterpret_cast<NamedDecl *>(*I)
- ->getIdentifierNamespace() == Decl::IDNS_Using)
+ (*I)->getIdentifierNamespace() == Decl::IDNS_Using)
++I;
}
- Vec.insert(I, reinterpret_cast<uintptr_t>(D));
+ Vec.insert(I, D);
// All other declarations go at the end of the list, but before any
// tag declarations. But we can be clever about tag declarations
// because there can only ever be one in a scope.
- } else if (reinterpret_cast<NamedDecl *>(Vec.back())
- ->hasTagIdentifierNamespace()) {
- uintptr_t TagD = Vec.back();
- Vec.back() = reinterpret_cast<uintptr_t>(D);
+ } else if (Vec.back()->hasTagIdentifierNamespace()) {
+ NamedDecl *TagD = Vec.back();
+ Vec.back() = D;
Vec.push_back(TagD);
} else
- Vec.push_back(reinterpret_cast<uintptr_t>(D));
+ Vec.push_back(D);
}
};
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 2807d16..4b5e6fd 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -68,16 +68,16 @@ public:
SourceLocation FriendL);
static FriendDecl *Create(ASTContext &C, EmptyShell Empty);
- /// If this friend declaration names an (untemplated but
- /// possibly dependent) type, return the type; otherwise
- /// return null. This is used only for C++0x's unelaborated
- /// friend type declarations.
+ /// If this friend declaration names an (untemplated but possibly
+ /// dependent) type, return the type; otherwise return null. This
+ /// is used for elaborated-type-specifiers and, in C++0x, for
+ /// arbitrary friend type declarations.
TypeSourceInfo *getFriendType() const {
return Friend.dyn_cast<TypeSourceInfo*>();
}
- /// If this friend declaration doesn't name an unelaborated
- /// type, return the inner declaration.
+ /// If this friend declaration doesn't name a type, return the inner
+ /// declaration.
NamedDecl *getFriendDecl() const {
return Friend.dyn_cast<NamedDecl*>();
}
@@ -92,8 +92,8 @@ public:
static bool classof(const FriendDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::Friend; }
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// An iterator over the friend declarations of a class.
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index e1fae8f..030291e 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -34,7 +34,6 @@ private:
public:
static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
- void Destroy(ASTContext& C);
unsigned size() const { return NumDecls; }
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 30f63d8..ad26748 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -21,7 +21,6 @@ namespace clang {
class Expr;
class Stmt;
class FunctionDecl;
-class AttributeList;
class RecordDecl;
class ObjCIvarDecl;
class ObjCMethodDecl;
@@ -41,12 +40,6 @@ protected:
public:
ObjCListBase() : List(0), NumElts(0) {}
- ~ObjCListBase() {
- assert(List == 0 && "Destroy should have been called before dtor");
- }
-
- void Destroy(ASTContext &Ctx);
-
unsigned size() const { return NumElts; }
bool empty() const { return NumElts == 0; }
@@ -92,7 +85,6 @@ public:
void set(ObjCProtocolDecl* const* InList, unsigned Elts,
const SourceLocation *Locs, ASTContext &Ctx);
- void Destroy(ASTContext &Ctx);
};
@@ -128,6 +120,9 @@ private:
// Synthesized declaration method for a property setter/getter
bool IsSynthesized : 1;
+
+ // Method has a definition.
+ bool IsDefined : 1;
// NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
/// @required/@optional
@@ -171,29 +166,25 @@ private:
bool isInstance = true,
bool isVariadic = false,
bool isSynthesized = false,
+ bool isDefined = false,
ImplementationControl impControl = None,
unsigned numSelectorArgs = 0)
: NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
DeclContext(ObjCMethod),
IsInstance(isInstance), IsVariadic(isVariadic),
IsSynthesized(isSynthesized),
+ IsDefined(isDefined),
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
NumSelectorArgs(numSelectorArgs), MethodDeclType(T),
ResultTInfo(ResultTInfo),
EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
- virtual ~ObjCMethodDecl() {}
-
/// \brief A definition will return its interface declaration.
/// An interface declaration will return its definition.
/// Otherwise it will return itself.
virtual ObjCMethodDecl *getNextRedeclaration();
public:
-
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
static ObjCMethodDecl *Create(ASTContext &C,
SourceLocation beginLoc,
SourceLocation endLoc, Selector SelInfo,
@@ -203,6 +194,7 @@ public:
bool isInstance = true,
bool isVariadic = false,
bool isSynthesized = false,
+ bool isDefined = false,
ImplementationControl impControl = None,
unsigned numSelectorArgs = 0);
@@ -296,6 +288,9 @@ public:
bool isSynthesized() const { return IsSynthesized; }
void setSynthesized(bool isSynth) { IsSynthesized = isSynth; }
+
+ bool isDefined() const { return IsDefined; }
+ void setDefined(bool isDefined) { IsDefined = isDefined; }
// Related to protocols declared in @protocol
void setDeclImplementation(ImplementationControl ic) {
@@ -326,21 +321,6 @@ public:
}
};
-/// ObjCMethodList - a linked list of methods with different signatures.
-struct ObjCMethodList {
- ObjCMethodDecl *Method;
- ObjCMethodList *Next;
-
- ObjCMethodList() {
- Method = 0;
- Next = 0;
- }
- ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) {
- Method = M;
- Next = C;
- }
-};
-
/// ObjCContainerDecl - Represents a container for method declarations.
/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
/// ObjCProtocolDecl, and ObjCImplDecl.
@@ -355,8 +335,6 @@ public:
IdentifierInfo *Id)
: NamedDecl(DK, DC, L, Id), DeclContext(DK) {}
- virtual ~ObjCContainerDecl() {}
-
// Iterator access to properties.
typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
prop_iterator prop_begin() const {
@@ -465,12 +443,19 @@ class ObjCInterfaceDecl : public ObjCContainerDecl {
/// Class's super class.
ObjCInterfaceDecl *SuperClass;
- /// Protocols referenced in interface header declaration
+ /// Protocols referenced in the @interface declaration
ObjCProtocolList ReferencedProtocols;
+
+ /// Protocols reference in both the @interface and class extensions.
+ ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
/// List of categories defined for this class.
/// FIXME: Why is this a linked list??
ObjCCategoryDecl *CategoryList;
+
+ /// IvarList - List of all ivars defined by this class; including class
+ /// extensions and implementation. This list is built lazily.
+ ObjCIvarDecl *IvarList;
bool ForwardDecl:1; // declared with @class.
bool InternalInterface:1; // true - no @interface for @implementation
@@ -482,13 +467,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl {
ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
SourceLocation CLoc, bool FD, bool isInternal);
- virtual ~ObjCInterfaceDecl() {}
-
public:
-
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation atLoc,
IdentifierInfo *Id,
@@ -513,25 +492,49 @@ public:
}
typedef ObjCProtocolList::iterator protocol_iterator;
- protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
- protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
+
+ protocol_iterator protocol_begin() const {
+ return ReferencedProtocols.begin();
+ }
+ protocol_iterator protocol_end() const {
+ return ReferencedProtocols.end();
+ }
+
typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+
protocol_loc_iterator protocol_loc_begin() const {
return ReferencedProtocols.loc_begin();
}
+
protocol_loc_iterator protocol_loc_end() const {
return ReferencedProtocols.loc_end();
}
- unsigned protocol_size() const { return ReferencedProtocols.size(); }
+
+ typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
+
+ all_protocol_iterator all_referenced_protocol_begin() const {
+ return AllReferencedProtocols.empty() ? protocol_begin()
+ : AllReferencedProtocols.begin();
+ }
+ all_protocol_iterator all_referenced_protocol_end() const {
+ return AllReferencedProtocols.empty() ? protocol_end()
+ : AllReferencedProtocols.end();
+ }
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+
ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); }
ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); }
+
unsigned ivar_size() const {
return std::distance(ivar_begin(), ivar_end());
}
+
bool ivar_empty() const { return ivar_begin() == ivar_end(); }
-
+
+ ObjCIvarDecl *all_declared_ivar_begin();
+ void setIvarList(ObjCIvarDecl *ivar) { IvarList = ivar; }
+
/// setProtocolList - Set the list of protocols that this interface
/// implements.
void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
@@ -543,7 +546,6 @@ public:
/// into the protocol list for this class.
void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
unsigned Num,
- const SourceLocation *Locs,
ASTContext &C);
bool isForwardDecl() const { return ForwardDecl; }
@@ -625,6 +627,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCInterfaceDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCInterface; }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
@@ -650,21 +655,26 @@ public:
private:
ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation L, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW)
+ QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
+ bool synthesized)
: FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
- DeclAccess(ac) {}
+ NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation L, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
- AccessControl ac, Expr *BW = NULL);
+ AccessControl ac, Expr *BW = NULL,
+ bool synthesized=false);
/// \brief Return the class interface that this ivar is logically contained
/// in; this is either the interface where the ivar was declared, or the
/// interface the ivar is conceptually a part of in the case of synthesized
/// ivars.
const ObjCInterfaceDecl *getContainingInterface() const;
+
+ ObjCIvarDecl *getNextIvar() { return NextIvar; }
+ void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
void setAccessControl(AccessControl ac) { DeclAccess = ac; }
@@ -674,13 +684,21 @@ public:
return DeclAccess == None ? Protected : AccessControl(DeclAccess);
}
+ void setSynthesize(bool synth) { Synthesized = synth; }
+ bool getSynthesize() const { return Synthesized; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCIvarDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCIvar; }
private:
+ /// NextIvar - Next Ivar in the list of ivars declared in class; class's
+ /// extensions and class's implementation
+ ObjCIvarDecl *NextIvar;
+
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
unsigned DeclAccess : 3;
+ unsigned Synthesized : 1;
};
@@ -700,8 +718,6 @@ public:
IdentifierInfo *Id, QualType T,
Expr *BW);
- virtual void Destroy(ASTContext& C);
-
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
@@ -745,15 +761,10 @@ class ObjCProtocolDecl : public ObjCContainerDecl {
isForwardProtoDecl(true) {
}
- virtual ~ObjCProtocolDecl() {}
-
public:
static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id);
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
const ObjCProtocolList &getReferencedProtocols() const {
return ReferencedProtocols;
}
@@ -822,12 +833,7 @@ private:
ObjCClassDecl(DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *const *Elts, const SourceLocation *Locs,
unsigned nElts, ASTContext &C);
- virtual ~ObjCClassDecl() {}
public:
-
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *const *Elts = 0,
const SourceLocation *Locs = 0,
@@ -860,7 +866,6 @@ class ObjCForwardProtocolDecl : public Decl {
ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
ObjCProtocolDecl *const *Elts, unsigned nElts,
const SourceLocation *Locs, ASTContext &C);
- virtual ~ObjCForwardProtocolDecl() {}
public:
static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC,
@@ -874,9 +879,6 @@ public:
return Create(C, DC, L, 0, 0, 0);
}
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
typedef ObjCProtocolList::iterator protocol_iterator;
protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
@@ -928,6 +930,9 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
/// FIXME: this should not be a singly-linked list. Move storage elsewhere.
ObjCCategoryDecl *NextClassCategory;
+ /// true of class extension has at least one bitfield ivar.
+ bool HasSynthBitfield : 1;
+
/// \brief The location of the '@' in '@interface'
SourceLocation AtLoc;
@@ -938,8 +943,8 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
IdentifierInfo *Id)
: ObjCContainerDecl(ObjCCategory, DC, ClassNameLoc, Id),
- ClassInterface(0), NextClassCategory(0), AtLoc(AtLoc),
- CategoryNameLoc(CategoryNameLoc) {
+ ClassInterface(0), NextClassCategory(0), HasSynthBitfield(false),
+ AtLoc(AtLoc), CategoryNameLoc(CategoryNameLoc) {
}
public:
@@ -991,6 +996,9 @@ public:
bool IsClassExtension() const { return getIdentifier() == 0; }
const ObjCCategoryDecl *getNextClassExtension() const;
+ bool hasSynthBitfield() const { return HasSynthBitfield; }
+ void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
+
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
ivar_iterator ivar_begin() const {
return ivar_iterator(decls_begin());
@@ -1032,8 +1040,6 @@ protected:
ClassInterface(classInterface) {}
public:
- virtual ~ObjCImplDecl() {}
-
const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
void setClassInterface(ObjCInterfaceDecl *IFace);
@@ -1165,11 +1171,15 @@ class ObjCImplementationDecl : public ObjCImplDecl {
CXXBaseOrMemberInitializer **IvarInitializers;
unsigned NumIvarInitializers;
+ /// true of class extension has at least one bitfield ivar.
+ bool HasSynthBitfield : 1;
+
ObjCImplementationDecl(DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *classInterface,
ObjCInterfaceDecl *superDecl)
: ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
- SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0) {}
+ SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0),
+ HasSynthBitfield(false) {}
public:
static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -1207,6 +1217,9 @@ public:
void setIvarInitializers(ASTContext &C,
CXXBaseOrMemberInitializer ** initializers,
unsigned numInitializers);
+
+ bool hasSynthBitfield() const { return HasSynthBitfield; }
+ void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
/// getIdentifier - Get the identifier that names the class
/// interface associated with this implementation.
@@ -1262,6 +1275,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCImplementationDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCImplementation; }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 135dd3a..b532668 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -23,6 +23,7 @@ namespace clang {
class TemplateParameterList;
class TemplateDecl;
+class RedeclarableTemplateDecl;
class FunctionTemplateDecl;
class ClassTemplateDecl;
class ClassTemplatePartialSpecializationDecl;
@@ -193,13 +194,6 @@ public:
TemplateArgumentList() : NumFlatArguments(0), NumStructuredArguments(0) { }
- /// Used to release the memory associated with a TemplateArgumentList
- /// object. FIXME: This is currently not called anywhere, but the
- /// memory will still be freed when using a BumpPtrAllocator.
- void Destroy(ASTContext &C);
-
- ~TemplateArgumentList();
-
/// \brief Copies the template arguments into a locally new[]'d array.
void init(ASTContext &Context,
const TemplateArgument *Args, unsigned NumArgs);
@@ -255,8 +249,6 @@ protected:
: NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
TemplateParams(Params) { }
public:
- ~TemplateDecl();
-
/// Get the list of template parameters
TemplateParameterList *getTemplateParameters() const {
return TemplateParams;
@@ -268,6 +260,7 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateDecl *D) { return true; }
+ static bool classof(const RedeclarableTemplateDecl *D) { return true; }
static bool classof(const FunctionTemplateDecl *D) { return true; }
static bool classof(const ClassTemplateDecl *D) { return true; }
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
@@ -490,122 +483,179 @@ public:
}
};
-/// Declaration of a template function.
-class FunctionTemplateDecl : public TemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
+/// Declaration of a redeclarable template.
+class RedeclarableTemplateDecl : public TemplateDecl {
+
+ RedeclarableTemplateDecl *getPreviousDeclarationImpl() {
+ return CommonOrPrev.dyn_cast<RedeclarableTemplateDecl*>();
+ }
+
+ RedeclarableTemplateDecl *getCanonicalDeclImpl();
+
+ void setPreviousDeclarationImpl(RedeclarableTemplateDecl *Prev);
+
+ RedeclarableTemplateDecl *getInstantiatedFromMemberTemplateImpl() {
+ return getCommonPtr()->InstantiatedFromMember.getPointer();
+ }
+
+ void setInstantiatedFromMemberTemplateImpl(RedeclarableTemplateDecl *TD) {
+ assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
+ getCommonPtr()->InstantiatedFromMember.setPointer(TD);
+ }
+
protected:
- /// \brief Data that is common to all of the declarations of a given
- /// function template.
- struct Common {
- Common() : InstantiatedFromMember(0, false) { }
+ template <typename EntryType> struct SpecEntryTraits {
+ typedef EntryType DeclType;
- /// \brief The function template specializations for this function
- /// template, including explicit specializations and instantiations.
- llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+ static DeclType *getMostRecentDeclaration(EntryType *D) {
+ return D->getMostRecentDeclaration();
+ }
+ };
+
+ template <typename EntryType,
+ typename _SETraits = SpecEntryTraits<EntryType>,
+ typename _DeclType = typename _SETraits::DeclType>
+ class SpecIterator : public std::iterator<std::forward_iterator_tag,
+ _DeclType*, ptrdiff_t,
+ _DeclType*, _DeclType*> {
+ typedef _SETraits SETraits;
+ typedef _DeclType DeclType;
+
+ typedef typename llvm::FoldingSet<EntryType>::iterator SetIteratorType;
+
+ SetIteratorType SetIter;
+
+ public:
+ SpecIterator() : SetIter() {}
+ SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
+
+ DeclType *operator*() const {
+ return SETraits::getMostRecentDeclaration(&*SetIter);
+ }
+ DeclType *operator->() const { return **this; }
+
+ SpecIterator &operator++() { ++SetIter; return *this; }
+ SpecIterator operator++(int) {
+ SpecIterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ bool operator==(SpecIterator Other) const {
+ return SetIter == Other.SetIter;
+ }
+ bool operator!=(SpecIterator Other) const {
+ return SetIter != Other.SetIter;
+ }
+ };
+
+ template <typename EntryType>
+ SpecIterator<EntryType> makeSpecIterator(llvm::FoldingSet<EntryType> &Specs,
+ bool isEnd) {
+ return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
+ }
+
+ template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
+ findSpecializationImpl(llvm::FoldingSet<EntryType> &Specs,
+ const TemplateArgument *Args, unsigned NumArgs,
+ void *&InsertPos);
+
+ struct CommonBase {
+ CommonBase() : InstantiatedFromMember(0, false) { }
- /// \brief The member function template from which this was most
+ /// \brief The template from which this was most
/// directly instantiated (or null).
///
- /// The boolean value indicates whether this member function template
+ /// The boolean value indicates whether this template
/// was explicitly specialized.
- llvm::PointerIntPair<FunctionTemplateDecl*, 1, bool> InstantiatedFromMember;
+ llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
+ InstantiatedFromMember;
+
+ /// \brief The latest declaration of this template.
+ RedeclarableTemplateDecl *Latest;
};
/// \brief A pointer to the previous declaration (if this is a redeclaration)
- /// or to the data that is common to all declarations of this function
- /// template.
- llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
+ /// or to the data that is common to all declarations of this template.
+ llvm::PointerUnion<CommonBase*, RedeclarableTemplateDecl*> CommonOrPrev;
- /// \brief Retrieves the "common" pointer shared by all
- /// (re-)declarations of the same function template. Calling this routine
- /// may implicitly allocate memory for the common pointer.
- Common *getCommonPtr();
+ /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
+ /// the same template. Calling this routine may implicitly allocate memory
+ /// for the common pointer.
+ CommonBase *getCommonPtr();
- FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
- CommonOrPrev((Common*)0) { }
+ virtual CommonBase *newCommon() = 0;
-public:
- void Destroy(ASTContext &C);
+ // Construct a template decl with name, parameters, and templated element.
+ RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params,
+ NamedDecl *Decl)
+ : TemplateDecl(DK, DC, L, Name, Params, Decl),
+ CommonOrPrev((CommonBase*)0) { }
- /// Get the underlying function declaration of the template.
- FunctionDecl *getTemplatedDecl() const {
- return static_cast<FunctionDecl*>(TemplatedDecl);
- }
+public:
+ template <class decl_type> friend class RedeclarableTemplate;
- /// \brief Retrieve the set of function template specializations of this
- /// function template.
- llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
- return getCommonPtr()->Specializations;
+ RedeclarableTemplateDecl *getCanonicalDecl() {
+ return getCanonicalDeclImpl();
}
- /// \brief Retrieve the previous declaration of this function template, or
+ /// \brief Retrieve the previous declaration of this template, or
/// NULL if no such declaration exists.
- const FunctionTemplateDecl *getPreviousDeclaration() const {
- return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+ RedeclarableTemplateDecl *getPreviousDeclaration() {
+ return getPreviousDeclarationImpl();
}
- /// \brief Retrieve the previous declaration of this function template, or
+ /// \brief Retrieve the previous declaration of this template, or
/// NULL if no such declaration exists.
- FunctionTemplateDecl *getPreviousDeclaration() {
- return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+ const RedeclarableTemplateDecl *getPreviousDeclaration() const {
+ return
+ const_cast<RedeclarableTemplateDecl*>(this)->getPreviousDeclaration();
}
- /// \brief Set the previous declaration of this function template.
- void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
- if (Prev)
- CommonOrPrev = Prev;
+ /// \brief Retrieve the first declaration of this template, or itself
+ /// if this the first one.
+ RedeclarableTemplateDecl *getFirstDeclaration() {
+ return getCanonicalDecl();
}
- virtual FunctionTemplateDecl *getCanonicalDecl();
+ /// \brief Retrieve the first declaration of this template, or itself
+ /// if this the first one.
+ const RedeclarableTemplateDecl *getFirstDeclaration() const {
+ return
+ const_cast<RedeclarableTemplateDecl*>(this)->getFirstDeclaration();
+ }
- /// \brief Retrieve the member function template that this function template
- /// was instantiated from.
- ///
- /// This routine will return non-NULL for member function templates of
- /// class templates. For example, given:
- ///
- /// \code
- /// template <typename T>
- /// struct X {
- /// template <typename U> void f();
- /// };
- /// \endcode
- ///
- /// X<int>::A<float> is a CXXMethodDecl (whose parent is X<int>, a
- /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
- /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
- /// X<int>) for which getInstantiatedFromMemberTemplate() will return
- /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
- /// ClassTemplateDecl).
- ///
- /// \returns NULL if this is not an instantiation of a member function
- /// template.
- FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
- return getCommonPtr()->InstantiatedFromMember.getPointer();
+ /// \brief Retrieve the most recent declaration of this template, or itself
+ /// if this the most recent one.
+ RedeclarableTemplateDecl *getMostRecentDeclaration() {
+ return getCommonPtr()->Latest;
}
- void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *FTD) {
- assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
- getCommonPtr()->InstantiatedFromMember.setPointer(FTD);
+ /// \brief Retrieve the most recent declaration of this template, or itself
+ /// if this the most recent one.
+ const RedeclarableTemplateDecl *getMostRecentDeclaration() const {
+ return
+ const_cast<RedeclarableTemplateDecl*>(this)->getMostRecentDeclaration();
}
/// \brief Determines whether this template was a specialization of a
/// member template.
///
- /// In the following example, the function template \c X<int>::f is a
- /// member specialization.
+ /// In the following example, the function template \c X<int>::f and the
+ /// member template \c X<int>::Inner are member specializations.
///
/// \code
/// template<typename T>
/// struct X {
/// template<typename U> void f(T, U);
+ /// template<typename U> struct Inner;
/// };
///
/// template<> template<typename T>
/// void X<int>::f(int, T);
+ /// template<> template<typename T>
+ /// struct X<int>::Inner { /* ... */ };
/// \endcode
bool isMemberSpecialization() {
return getCommonPtr()->InstantiatedFromMember.getInt();
@@ -618,6 +668,197 @@ public:
getCommonPtr()->InstantiatedFromMember.setInt(true);
}
+ /// \brief Retrieve the previous declaration of this template, or
+ /// NULL if no such declaration exists.
+ RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() {
+ return getInstantiatedFromMemberTemplateImpl();
+ }
+
+ virtual RedeclarableTemplateDecl *getNextRedeclaration();
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const RedeclarableTemplateDecl *D) { return true; }
+ static bool classof(const FunctionTemplateDecl *D) { return true; }
+ static bool classof(const ClassTemplateDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
+ }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+};
+
+template <class decl_type>
+class RedeclarableTemplate {
+ RedeclarableTemplateDecl *thisDecl() {
+ return static_cast<decl_type*>(this);
+ }
+
+public:
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ decl_type *getPreviousDeclaration() {
+ return static_cast<decl_type*>(thisDecl()->getPreviousDeclarationImpl());
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ const decl_type *getPreviousDeclaration() const {
+ return const_cast<RedeclarableTemplate*>(this)->getPreviousDeclaration();
+ }
+
+ /// \brief Set the previous declaration of this function template.
+ void setPreviousDeclaration(decl_type *Prev) {
+ thisDecl()->setPreviousDeclarationImpl(Prev);
+ }
+
+ decl_type *getCanonicalDecl() {
+ return static_cast<decl_type*>(thisDecl()->getCanonicalDeclImpl());
+ }
+
+ const decl_type *getCanonicalDecl() const {
+ return const_cast<RedeclarableTemplate*>(this)->getCanonicalDecl();
+ }
+
+ /// \brief Retrieve the member template that this template was instantiated
+ /// from.
+ ///
+ /// This routine will return non-NULL for member templates of
+ /// class templates. For example, given:
+ ///
+ /// \code
+ /// template <typename T>
+ /// struct X {
+ /// template <typename U> void f();
+ /// template <typename U> struct A {};
+ /// };
+ /// \endcode
+ ///
+ /// X<int>::f<float> is a CXXMethodDecl (whose parent is X<int>, a
+ /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
+ /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
+ /// X<int>) for which getInstantiatedFromMemberTemplate() will return
+ /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
+ /// ClassTemplateDecl).
+ ///
+ /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
+ /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
+ /// return X<int>::A<U>, a ClassTemplateDecl (whose parent is again
+ /// X<int>) for which getInstantiatedFromMemberTemplate() will return
+ /// X<T>::A<U>, a ClassTemplateDecl (whose parent is X<T>, also a CTD).
+ ///
+ /// \returns NULL if this is not an instantiation of a member template.
+ decl_type *getInstantiatedFromMemberTemplate() {
+ return static_cast<decl_type*>(
+ thisDecl()->getInstantiatedFromMemberTemplateImpl());
+ }
+
+ void setInstantiatedFromMemberTemplate(decl_type *TD) {
+ thisDecl()->setInstantiatedFromMemberTemplateImpl(TD);
+ }
+};
+
+template <> struct RedeclarableTemplateDecl::
+SpecEntryTraits<FunctionTemplateSpecializationInfo> {
+ typedef FunctionDecl DeclType;
+
+ static DeclType *
+ getMostRecentDeclaration(FunctionTemplateSpecializationInfo *I) {
+ return I->Function->getMostRecentDeclaration();
+ }
+};
+
+/// Declaration of a template function.
+class FunctionTemplateDecl : public RedeclarableTemplateDecl,
+ public RedeclarableTemplate<FunctionTemplateDecl> {
+ static void DeallocateCommon(void *Ptr);
+
+protected:
+ typedef RedeclarableTemplate<FunctionTemplateDecl> redeclarable_base;
+
+ /// \brief Data that is common to all of the declarations of a given
+ /// function template.
+ struct Common : CommonBase {
+ /// \brief The function template specializations for this function
+ /// template, including explicit specializations and instantiations.
+ llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+ };
+
+ FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl)
+ : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
+
+ CommonBase *newCommon();
+
+ Common *getCommonPtr() {
+ return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
+ }
+
+ friend void FunctionDecl::setFunctionTemplateSpecialization(
+ FunctionTemplateDecl *Template,
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos,
+ TemplateSpecializationKind TSK,
+ const TemplateArgumentListInfo *TemplateArgsAsWritten,
+ SourceLocation PointOfInstantiation);
+
+ /// \brief Retrieve the set of function template specializations of this
+ /// function template.
+ llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
+ return getCommonPtr()->Specializations;
+ }
+
+public:
+ /// Get the underlying function declaration of the template.
+ FunctionDecl *getTemplatedDecl() const {
+ return static_cast<FunctionDecl*>(TemplatedDecl);
+ }
+
+ /// Returns whether this template declaration defines the primary
+ /// pattern.
+ bool isThisDeclarationADefinition() const {
+ return getTemplatedDecl()->isThisDeclarationADefinition();
+ }
+
+ /// \brief Return the specialization with the provided arguments if it exists,
+ /// otherwise return the insertion point.
+ FunctionDecl *findSpecialization(const TemplateArgument *Args,
+ unsigned NumArgs, void *&InsertPos);
+
+ FunctionTemplateDecl *getCanonicalDecl() {
+ return redeclarable_base::getCanonicalDecl();
+ }
+ const FunctionTemplateDecl *getCanonicalDecl() const {
+ return redeclarable_base::getCanonicalDecl();
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ FunctionTemplateDecl *getPreviousDeclaration() {
+ return redeclarable_base::getPreviousDeclaration();
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ const FunctionTemplateDecl *getPreviousDeclaration() const {
+ return redeclarable_base::getPreviousDeclaration();
+ }
+
+ FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
+ return redeclarable_base::getInstantiatedFromMemberTemplate();
+ }
+
+ typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
+
+ spec_iterator spec_begin() {
+ return makeSpecIterator(getSpecializations(), false);
+ }
+
+ spec_iterator spec_end() {
+ return makeSpecIterator(getSpecializations(), true);
+ }
+
/// Create a template function node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -630,8 +871,8 @@ public:
static bool classof(const FunctionTemplateDecl *D) { return true; }
static bool classofKind(Kind K) { return K == FunctionTemplate; }
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
//===----------------------------------------------------------------------===//
@@ -781,8 +1022,7 @@ class NonTypeTemplateParmDecl
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo)
- : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None,
- VarDecl::None),
+ : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, SC_None, SC_None),
TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false)
{ }
@@ -904,13 +1144,20 @@ public:
DefaultArgumentWasInherited = false;
}
+ SourceRange getSourceRange() const {
+ SourceLocation End = getLocation();
+ if (hasDefaultArgument() && !defaultArgumentWasInherited())
+ End = getDefaultArgument().getSourceRange().getEnd();
+ return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// \brief Represents a class template specialization, which refers to
@@ -991,12 +1238,21 @@ public:
static ClassTemplateSpecializationDecl *
Create(ASTContext &Context, EmptyShell Empty);
- virtual void Destroy(ASTContext& C);
-
virtual void getNameForDiagnostic(std::string &S,
const PrintingPolicy &Policy,
bool Qualified) const;
+ ClassTemplateSpecializationDecl *getMostRecentDeclaration() {
+ CXXRecordDecl *Recent
+ = cast<CXXRecordDecl>(CXXRecordDecl::getMostRecentDeclaration());
+ if (!isa<ClassTemplateSpecializationDecl>(Recent)) {
+ // FIXME: Does injected class name need to be in the redeclarations chain?
+ assert(Recent->isInjectedClassName() && Recent->getPreviousDeclaration());
+ Recent = Recent->getPreviousDeclaration();
+ }
+ return cast<ClassTemplateSpecializationDecl>(Recent);
+ }
+
/// \brief Retrieve the template that this specialization specializes.
ClassTemplateDecl *getSpecializedTemplate() const;
@@ -1044,7 +1300,8 @@ public:
if (getSpecializationKind() != TSK_ImplicitInstantiation &&
getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
- return (ClassTemplateDecl*)0;
+ return llvm::PointerUnion<ClassTemplateDecl *,
+ ClassTemplatePartialSpecializationDecl *>();
if (SpecializedPartialSpecialization *PartialSpec
= SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
@@ -1123,7 +1380,8 @@ public:
/// \brief Sets the type of this specialization as it was written by
/// the user. This will be a class template specialization type.
void setTypeAsWritten(TypeSourceInfo *T) {
- if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
+ if (!ExplicitInfo)
+ ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->TypeAsWritten = T;
}
/// \brief Gets the type of this specialization as it was written by
@@ -1138,13 +1396,15 @@ public:
}
/// \brief Sets the location of the extern keyword.
void setExternLoc(SourceLocation Loc) {
- if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
+ if (!ExplicitInfo)
+ ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->ExternLoc = Loc;
}
/// \brief Sets the location of the template keyword.
void setTemplateKeywordLoc(SourceLocation Loc) {
- if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
+ if (!ExplicitInfo)
+ ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->TemplateKeywordLoc = Loc;
}
/// \brief Gets the location of the template keyword, if present.
@@ -1242,6 +1502,11 @@ public:
static ClassTemplatePartialSpecializationDecl *
Create(ASTContext &Context, EmptyShell Empty);
+ ClassTemplatePartialSpecializationDecl *getMostRecentDeclaration() {
+ return cast<ClassTemplatePartialSpecializationDecl>(
+ ClassTemplateSpecializationDecl::getMostRecentDeclaration());
+ }
+
/// Get the list of template parameters
TemplateParameterList *getTemplateParameters() const {
return TemplateParams;
@@ -1355,15 +1620,16 @@ public:
};
/// Declaration of a class template.
-class ClassTemplateDecl : public TemplateDecl {
+class ClassTemplateDecl : public RedeclarableTemplateDecl,
+ public RedeclarableTemplate<ClassTemplateDecl> {
static void DeallocateCommon(void *Ptr);
protected:
+ typedef RedeclarableTemplate<ClassTemplateDecl> redeclarable_base;
+
/// \brief Data that is common to all of the declarations of a given
/// class template.
- struct Common {
- Common() : InstantiatedFromMember(0, 0) {}
-
+ struct Common : CommonBase {
/// \brief The class template specializations for this class
/// template, including explicit specializations and instantiations.
llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
@@ -1375,28 +1641,29 @@ protected:
/// \brief The injected-class-name type for this class template.
QualType InjectedClassNameType;
-
- /// \brief The templated member class from which this was most
- /// directly instantiated (or null).
- ///
- /// The boolean value indicates whether this member class template
- /// was explicitly specialized.
- llvm::PointerIntPair<ClassTemplateDecl *, 1, bool> InstantiatedFromMember;
};
- /// \brief A pointer to the previous declaration (if this is a redeclaration)
- /// or to the data that is common to all declarations of this class template.
- llvm::PointerUnion<Common*, ClassTemplateDecl*> CommonOrPrev;
+ /// \brief Retrieve the set of specializations of this class template.
+ llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
+ return getCommonPtr()->Specializations;
+ }
- /// \brief Retrieves the "common" pointer shared by all
- /// (re-)declarations of the same class template. Calling this routine
- /// may implicitly allocate memory for the common pointer.
- Common *getCommonPtr();
+ /// \brief Retrieve the set of partial specializations of this class
+ /// template.
+ llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
+ getPartialSpecializations() {
+ return getCommonPtr()->PartialSpecializations;
+ }
ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
- CommonOrPrev((Common*)0) { }
+ : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
+
+ CommonBase *newCommon();
+
+ Common *getCommonPtr() {
+ return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
+ }
public:
/// Get the underlying class declarations of the template.
@@ -1404,48 +1671,71 @@ public:
return static_cast<CXXRecordDecl *>(TemplatedDecl);
}
- /// \brief Retrieve the previous declaration of this class template, or
- /// NULL if no such declaration exists.
- const ClassTemplateDecl *getPreviousDeclaration() const {
- return CommonOrPrev.dyn_cast<ClassTemplateDecl*>();
+ /// Returns whether this template declaration defines the primary
+ /// class pattern.
+ bool isThisDeclarationADefinition() const {
+ return getTemplatedDecl()->isThisDeclarationADefinition();
}
- /// \brief Retrieve the previous declaration of this function template, or
+ /// Create a class template node.
+ static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,
+ DeclarationName Name,
+ TemplateParameterList *Params,
+ NamedDecl *Decl,
+ ClassTemplateDecl *PrevDecl);
+
+ /// \brief Return the specialization with the provided arguments if it exists,
+ /// otherwise return the insertion point.
+ ClassTemplateSpecializationDecl *
+ findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
+ void *&InsertPos);
+
+ /// \brief Insert the specified specialization knowing that it is not already
+ /// in. InsertPos must be obtained from findSpecialization.
+ void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos) {
+ getSpecializations().InsertNode(D, InsertPos);
+ }
+
+ ClassTemplateDecl *getCanonicalDecl() {
+ return redeclarable_base::getCanonicalDecl();
+ }
+ const ClassTemplateDecl *getCanonicalDecl() const {
+ return redeclarable_base::getCanonicalDecl();
+ }
+
+ /// \brief Retrieve the previous declaration of this class template, or
/// NULL if no such declaration exists.
ClassTemplateDecl *getPreviousDeclaration() {
- return CommonOrPrev.dyn_cast<ClassTemplateDecl*>();
+ return redeclarable_base::getPreviousDeclaration();
}
- /// \brief Set the previous declaration of this class template.
- void setPreviousDeclaration(ClassTemplateDecl *Prev) {
- if (Prev)
- CommonOrPrev = Prev;
+ /// \brief Retrieve the previous declaration of this class template, or
+ /// NULL if no such declaration exists.
+ const ClassTemplateDecl *getPreviousDeclaration() const {
+ return redeclarable_base::getPreviousDeclaration();
}
- virtual ClassTemplateDecl *getCanonicalDecl();
-
- const ClassTemplateDecl *getCanonicalDecl() const {
- return const_cast<ClassTemplateDecl*>(this)->getCanonicalDecl();
+ ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
+ return redeclarable_base::getInstantiatedFromMemberTemplate();
}
- /// Create a class template node.
- static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl,
- ClassTemplateDecl *PrevDecl);
+ /// \brief Return the partial specialization with the provided arguments if it
+ /// exists, otherwise return the insertion point.
+ ClassTemplatePartialSpecializationDecl *
+ findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
+ void *&InsertPos);
- /// \brief Retrieve the set of specializations of this class template.
- llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
- return getCommonPtr()->Specializations;
+ /// \brief Insert the specified partial specialization knowing that it is not
+ /// already in. InsertPos must be obtained from findPartialSpecialization.
+ void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
+ void *InsertPos) {
+ getPartialSpecializations().InsertNode(D, InsertPos);
}
- /// \brief Retrieve the set of partial specializations of this class
- /// template.
- llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
- getPartialSpecializations() {
- return getCommonPtr()->PartialSpecializations;
+ /// \brief Return the next partial specialization sequence number.
+ unsigned getNextPartialSpecSequenceNumber() {
+ return getPartialSpecializations().size();
}
/// \brief Retrieve the partial specializations as an ordered list.
@@ -1455,12 +1745,24 @@ public:
/// \brief Find a class template partial specialization with the given
/// type T.
///
- /// \brief A dependent type that names a specialization of this class
+ /// \param T a dependent type that names a specialization of this class
/// template.
///
/// \returns the class template partial specialization that exactly matches
/// the type \p T, or NULL if no such partial specialization exists.
ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
+
+ /// \brief Find a class template partial specialization which was instantiated
+ /// from the given member partial specialization.
+ ///
+ /// \param D a member class template partial specialization.
+ ///
+ /// \returns the class template partial specialization which was instantiated
+ /// from the given member partial specialization, or NULL if no such partial
+ /// specialization exists.
+ ClassTemplatePartialSpecializationDecl *
+ findPartialSpecInstantiatedFromMember(
+ ClassTemplatePartialSpecializationDecl *D);
/// \brief Retrieve the template specialization type of the
/// injected-class-name for this class template.
@@ -1478,78 +1780,45 @@ public:
/// \endcode
QualType getInjectedClassNameSpecialization();
- /// \brief Retrieve the member class template that this class template was
- /// derived from.
- ///
- /// This routine will return non-NULL for templated member classes of
- /// class templates. For example, given:
- ///
- /// \code
- /// template <typename T>
- /// struct X {
- /// template <typename U> struct A {};
- /// };
- /// \endcode
- ///
- /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
- /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
- /// return X<int>::A<U>, a TemplateClassDecl (whose parent is again
- /// X<int>) for which getInstantiatedFromMemberTemplate() will return
- /// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
- ///
- /// \returns null if this is not an instantiation of a member class template.
- ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
- return getCommonPtr()->InstantiatedFromMember.getPointer();
+ typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
+
+ spec_iterator spec_begin() {
+ return makeSpecIterator(getSpecializations(), false);
}
- void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
- assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
- getCommonPtr()->InstantiatedFromMember.setPointer(CTD);
+ spec_iterator spec_end() {
+ return makeSpecIterator(getSpecializations(), true);
}
- /// \brief Determines whether this template was a specialization of a
- /// member template.
- ///
- /// In the following example, the member template \c X<int>::Inner is a
- /// member specialization.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> struct Inner;
- /// };
- ///
- /// template<> template<typename T>
- /// struct X<int>::Inner { /* ... */ };
- /// \endcode
- bool isMemberSpecialization() {
- return getCommonPtr()->InstantiatedFromMember.getInt();
+ typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
+ partial_spec_iterator;
+
+ partial_spec_iterator partial_spec_begin() {
+ return makeSpecIterator(getPartialSpecializations(), false);
}
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- getCommonPtr()->InstantiatedFromMember.setInt(true);
+
+ partial_spec_iterator partial_spec_end() {
+ return makeSpecIterator(getPartialSpecializations(), true);
}
-
+
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ClassTemplateDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ClassTemplate; }
- virtual void Destroy(ASTContext& C);
-
- friend class PCHDeclReader;
- friend class PCHDeclWriter;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// Declaration of a friend template. For example:
///
/// template <typename T> class A {
/// friend class MyVector<T>; // not a friend template
-/// template <typename U> friend class B; // friend template
+/// template <typename U> friend class B; // not a friend template
/// template <typename U> friend class Foo<T>::Nested; // friend template
+/// };
+/// NOTE: This class is not currently in use. All of the above
+/// will yield a FriendDecl, not a FriendTemplateDecl.
class FriendTemplateDecl : public Decl {
public:
typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
@@ -1580,6 +1849,12 @@ private:
FriendLoc(FriendLoc)
{}
+ FriendTemplateDecl(EmptyShell Empty)
+ : Decl(Decl::FriendTemplate, Empty),
+ NumParams(0),
+ Params(0)
+ {}
+
public:
static FriendTemplateDecl *Create(ASTContext &Context,
DeclContext *DC, SourceLocation Loc,
@@ -1588,6 +1863,8 @@ public:
FriendUnion Friend,
SourceLocation FriendLoc);
+ static FriendTemplateDecl *Create(ASTContext &Context, EmptyShell Empty);
+
/// If this friend declaration names a templated type (or
/// a dependent member type of a templated type), return that
/// type; otherwise return null.
@@ -1620,6 +1897,8 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
static bool classof(const FriendTemplateDecl *D) { return true; }
+
+ friend class ASTDeclReader;
};
/// Implementation of inline functions that require the template declarations
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 8a771d5..8bb6275 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -30,6 +30,7 @@ namespace clang {
class IdentifierInfo;
class MultiKeywordSelector;
class UsingDirectiveDecl;
+ class TypeSourceInfo;
/// DeclarationName - The name of a declaration. In the common case,
/// this just stores an IdentifierInfo pointer to a normal
@@ -367,6 +368,146 @@ public:
DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
};
+/// DeclarationNameLoc - Additional source/type location info
+/// for a declaration name. Needs a DeclarationName in order
+/// to be interpreted correctly.
+struct DeclarationNameLoc {
+ union {
+ // The source location for identifier stored elsewhere.
+ // struct {} Identifier;
+
+ // Type info for constructors, destructors and conversion functions.
+ // Locations (if any) for the tilde (destructor) or operator keyword
+ // (conversion) are stored elsewhere.
+ struct {
+ TypeSourceInfo* TInfo;
+ } NamedType;
+
+ // The location (if any) of the operator keyword is stored elsewhere.
+ struct {
+ unsigned BeginOpNameLoc;
+ unsigned EndOpNameLoc;
+ } CXXOperatorName;
+
+ // The location (if any) of the operator keyword is stored elsewhere.
+ struct {
+ unsigned OpNameLoc;
+ } CXXLiteralOperatorName;
+
+ // struct {} CXXUsingDirective;
+ // struct {} ObjCZeroArgSelector;
+ // struct {} ObjCOneArgSelector;
+ // struct {} ObjCMultiArgSelector;
+ };
+
+ DeclarationNameLoc(DeclarationName Name);
+ // FIXME: this should go away once all DNLocs are properly initialized.
+ DeclarationNameLoc() { NamedType.TInfo = 0; }
+}; // struct DeclarationNameLoc
+
+
+/// DeclarationNameInfo - A collector data type for bundling together
+/// a DeclarationName and the correspnding source/type location info.
+struct DeclarationNameInfo {
+private:
+ /// Name - The declaration name, also encoding name kind.
+ DeclarationName Name;
+ /// Loc - The main source location for the declaration name.
+ SourceLocation NameLoc;
+ /// Info - Further source/type location info for special kinds of names.
+ DeclarationNameLoc LocInfo;
+
+public:
+ // FIXME: remove it.
+ DeclarationNameInfo() {}
+
+ DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
+ : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
+
+ DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
+ DeclarationNameLoc LocInfo)
+ : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
+
+ /// getName - Returns the embedded declaration name.
+ DeclarationName getName() const { return Name; }
+ /// setName - Sets the embedded declaration name.
+ void setName(DeclarationName N) { Name = N; }
+
+ /// getLoc - Returns the main location of the declaration name.
+ SourceLocation getLoc() const { return NameLoc; }
+ /// setLoc - Sets the main location of the declaration name.
+ void setLoc(SourceLocation L) { NameLoc = L; }
+
+ const DeclarationNameLoc &getInfo() const { return LocInfo; }
+ DeclarationNameLoc &getInfo() { return LocInfo; }
+ void setInfo(const DeclarationNameLoc &Info) { LocInfo = Info; }
+
+ /// getNamedTypeInfo - Returns the source type info associated to
+ /// the name. Assumes it is a constructor, destructor or conversion.
+ TypeSourceInfo *getNamedTypeInfo() const {
+ assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
+ Name.getNameKind() == DeclarationName::CXXDestructorName ||
+ Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+ return LocInfo.NamedType.TInfo;
+ }
+ /// setNamedTypeInfo - Sets the source type info associated to
+ /// the name. Assumes it is a constructor, destructor or conversion.
+ void setNamedTypeInfo(TypeSourceInfo *TInfo) {
+ assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
+ Name.getNameKind() == DeclarationName::CXXDestructorName ||
+ Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+ LocInfo.NamedType.TInfo = TInfo;
+ }
+
+ /// getCXXOperatorNameRange - Gets the range of the operator name
+ /// (without the operator keyword). Assumes it is a (non-literal) operator.
+ SourceRange getCXXOperatorNameRange() const {
+ assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+ return SourceRange(
+ SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
+ SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
+ );
+ }
+ /// setCXXOperatorNameRange - Sets the range of the operator name
+ /// (without the operator keyword). Assumes it is a C++ operator.
+ void setCXXOperatorNameRange(SourceRange R) {
+ assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+ LocInfo.CXXOperatorName.BeginOpNameLoc = R.getBegin().getRawEncoding();
+ LocInfo.CXXOperatorName.EndOpNameLoc = R.getEnd().getRawEncoding();
+ }
+
+ /// getCXXLiteralOperatorNameLoc - Returns the location of the literal
+ /// operator name (not the operator keyword).
+ /// Assumes it is a literal operator.
+ SourceLocation getCXXLiteralOperatorNameLoc() const {
+ assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+ return SourceLocation::
+ getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
+ }
+ /// setCXXLiteralOperatorNameLoc - Sets the location of the literal
+ /// operator name (not the operator keyword).
+ /// Assumes it is a literal operator.
+ void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
+ assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+ LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
+ }
+
+ /// getAsString - Retrieve the human-readable string for this name.
+ std::string getAsString() const;
+
+ /// printName - Print the human-readable name to a stream.
+ void printName(llvm::raw_ostream &OS) const;
+
+ /// getBeginLoc - Retrieve the location of the first token.
+ SourceLocation getBeginLoc() const { return NameLoc; }
+ /// getEndLoc - Retrieve the location of the last token.
+ SourceLocation getEndLoc() const;
+ /// getSourceRange - The range of the declaration name.
+ SourceRange getSourceRange() const {
+ return SourceRange(getBeginLoc(), getEndLoc());
+ }
+};
+
/// Insertion operator for diagnostics. This allows sending DeclarationName's
/// into a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
@@ -385,6 +526,12 @@ inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
return PD;
}
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ DeclarationNameInfo DNInfo) {
+ DNInfo.printName(OS);
+ return OS;
+}
+
} // end namespace clang
namespace llvm {
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index ade2b09..48130be 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -18,6 +18,7 @@
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/OperationKinds.h"
#include "clang/AST/ASTVector.h"
#include "clang/AST/UsuallyTinyPtrVector.h"
#include "llvm/ADT/APSInt.h"
@@ -42,7 +43,7 @@ namespace clang {
class TemplateArgumentListInfo;
/// \brief A simple array of base specifiers.
-typedef UsuallyTinyPtrVector<const CXXBaseSpecifier> CXXBaseSpecifierArray;
+typedef llvm::SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
/// Expr - This represents one expression. Note that Expr's are subclasses of
/// Stmt. This allows an expression to be transparently used any place a Stmt
@@ -61,8 +62,14 @@ protected:
/// (C++ [temp.dep.constexpr]).
bool ValueDependent : 1;
+ /// ValueKind - The value classification of this expression.
+ /// Only actually used by certain subclasses.
+ unsigned ValueKind : 2;
+
+ enum { BitsRemaining = 28 };
+
Expr(StmtClass SC, QualType T, bool TD, bool VD)
- : Stmt(SC), TypeDependent(TD), ValueDependent(VD) {
+ : Stmt(SC), TypeDependent(TD), ValueDependent(VD), ValueKind(0) {
setType(T);
}
@@ -258,7 +265,6 @@ public:
/// function returning an rvalue reference.
/// lvalues and xvalues are collectively referred to as glvalues, while
/// prvalues and xvalues together form rvalues.
- /// If a
Classification Classify(ASTContext &Ctx) const {
return ClassifyImpl(Ctx, 0);
}
@@ -310,7 +316,7 @@ public:
}
/// isConstantInitializer - Returns true if this expression is a constant
/// initializer, which can be emitted at compile-time.
- bool isConstantInitializer(ASTContext &Ctx) const;
+ bool isConstantInitializer(ASTContext &Ctx, bool ForRef) const;
/// EvalResult is a struct with detailed info about an evaluated expression.
struct EvalResult {
@@ -521,10 +527,14 @@ class DeclRefExpr : public Expr {
// (2) the declaration's name was followed by an explicit template
// argument list.
llvm::PointerIntPair<ValueDecl *, 2> DecoratedD;
-
+
// Loc - The location of the declaration name itself.
SourceLocation Loc;
+ /// DNLoc - Provides source/type location info for the
+ /// declaration name embedded in DecoratedD.
+ DeclarationNameLoc DNLoc;
+
/// \brief Retrieve the qualifier that preceded the declaration name, if any.
NameQualifier *getNameQualifier() {
if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
@@ -537,31 +547,17 @@ class DeclRefExpr : public Expr {
const NameQualifier *getNameQualifier() const {
return const_cast<DeclRefExpr *>(this)->getNameQualifier();
}
-
- /// \brief Retrieve the explicit template argument list that followed the
- /// member template name, if any.
- ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
- if ((DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag) == 0)
- return 0;
-
- if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
- return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
-
- return reinterpret_cast<ExplicitTemplateArgumentList *>(
- getNameQualifier() + 1);
- }
-
- /// \brief Retrieve the explicit template argument list that followed the
- /// member template name, if any.
- const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
- return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgumentList();
- }
-
+
DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
ValueDecl *D, SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs,
QualType T);
+ DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+ ValueDecl *D, const DeclarationNameInfo &NameInfo,
+ const TemplateArgumentListInfo *TemplateArgs,
+ QualType T);
+
/// \brief Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty)
: Expr(DeclRefExprClass, Empty) { }
@@ -584,6 +580,14 @@ public:
QualType T,
const TemplateArgumentListInfo *TemplateArgs = 0);
+ static DeclRefExpr *Create(ASTContext &Context,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ ValueDecl *D,
+ const DeclarationNameInfo &NameInfo,
+ QualType T,
+ const TemplateArgumentListInfo *TemplateArgs = 0);
+
/// \brief Construct an empty declaration reference expression.
static DeclRefExpr *CreateEmpty(ASTContext &Context,
bool HasQualifier, unsigned NumTemplateArgs);
@@ -592,6 +596,10 @@ public:
const ValueDecl *getDecl() const { return DecoratedD.getPointer(); }
void setDecl(ValueDecl *NewD) { DecoratedD.setPointer(NewD); }
+ DeclarationNameInfo getNameInfo() const {
+ return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc);
+ }
+
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
virtual SourceRange getSourceRange() const;
@@ -619,53 +627,77 @@ public:
return getNameQualifier()->NNS;
}
- /// \brief Determines whether this member expression actually had a C++
- /// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgumentList() const {
- return DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag;
+ bool hasExplicitTemplateArgs() const {
+ return (DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name.
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+ assert(hasExplicitTemplateArgs());
+
+ if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(
+ getNameQualifier() + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgs();
}
+ /// \brief Retrieves the optional explicit template arguments.
+ /// This points to the same data as getExplicitTemplateArgs(), but
+ /// returns null if there are no explicit template arguments.
+ const ExplicitTemplateArgumentList *getExplicitTemplateArgsOpt() const {
+ if (!hasExplicitTemplateArgs()) return 0;
+ return &getExplicitTemplateArgs();
+ }
+
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgumentList())
- getExplicitTemplateArgumentList()->copyInto(List);
+ if (hasExplicitTemplateArgs())
+ getExplicitTemplateArgs().copyInto(List);
}
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
- if (!hasExplicitTemplateArgumentList())
+ if (!hasExplicitTemplateArgs())
return SourceLocation();
- return getExplicitTemplateArgumentList()->LAngleLoc;
+ return getExplicitTemplateArgs().LAngleLoc;
}
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
- if (!hasExplicitTemplateArgumentList())
+ if (!hasExplicitTemplateArgs())
return 0;
- return getExplicitTemplateArgumentList()->getTemplateArgs();
+ return getExplicitTemplateArgs().getTemplateArgs();
}
/// \brief Retrieve the number of template arguments provided as part of this
/// template-id.
unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgumentList())
+ if (!hasExplicitTemplateArgs())
return 0;
- return getExplicitTemplateArgumentList()->NumTemplateArgs;
+ return getExplicitTemplateArgs().NumTemplateArgs;
}
/// \brief Retrieve the location of the right angle bracket following the
/// template arguments ('>').
SourceLocation getRAngleLoc() const {
- if (!hasExplicitTemplateArgumentList())
+ if (!hasExplicitTemplateArgs())
return SourceLocation();
- return getExplicitTemplateArgumentList()->RAngleLoc;
+ return getExplicitTemplateArgs().RAngleLoc;
}
static bool classof(const Stmt *T) {
@@ -677,8 +709,8 @@ public:
virtual child_iterator child_begin();
virtual child_iterator child_end();
- friend class PCHStmtReader;
- friend class PCHStmtWriter;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
};
/// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
@@ -725,28 +757,84 @@ public:
virtual child_iterator child_end();
};
+/// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without
+/// leaking memory.
+///
+/// For large floats/integers, APFloat/APInt will allocate memory from the heap
+/// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator
+/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
+/// the APFloat/APInt values will never get freed. APNumericStorage uses
+/// ASTContext's allocator for memory allocation.
+class APNumericStorage {
+ unsigned BitWidth;
+ union {
+ uint64_t VAL; ///< Used to store the <= 64 bits integer value.
+ uint64_t *pVal; ///< Used to store the >64 bits integer value.
+ };
+
+ bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
+
+ APNumericStorage(const APNumericStorage&); // do not implement
+ APNumericStorage& operator=(const APNumericStorage&); // do not implement
+
+protected:
+ APNumericStorage() : BitWidth(0), VAL(0) { }
+
+ llvm::APInt getIntValue() const {
+ unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
+ if (NumWords > 1)
+ return llvm::APInt(BitWidth, NumWords, pVal);
+ else
+ return llvm::APInt(BitWidth, VAL);
+ }
+ void setIntValue(ASTContext &C, const llvm::APInt &Val);
+};
+
+class APIntStorage : public APNumericStorage {
+public:
+ llvm::APInt getValue() const { return getIntValue(); }
+ void setValue(ASTContext &C, const llvm::APInt &Val) { setIntValue(C, Val); }
+};
+
+class APFloatStorage : public APNumericStorage {
+public:
+ llvm::APFloat getValue() const { return llvm::APFloat(getIntValue()); }
+ void setValue(ASTContext &C, const llvm::APFloat &Val) {
+ setIntValue(C, Val.bitcastToAPInt());
+ }
+};
+
class IntegerLiteral : public Expr {
- llvm::APInt Value;
+ APIntStorage Num;
SourceLocation Loc;
+
+ /// \brief Construct an empty integer literal.
+ explicit IntegerLiteral(EmptyShell Empty)
+ : Expr(IntegerLiteralClass, Empty) { }
+
public:
// type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
// or UnsignedLongLongTy
- IntegerLiteral(const llvm::APInt &V, QualType type, SourceLocation l)
- : Expr(IntegerLiteralClass, type, false, false), Value(V), Loc(l) {
+ IntegerLiteral(ASTContext &C, const llvm::APInt &V,
+ QualType type, SourceLocation l)
+ : Expr(IntegerLiteralClass, type, false, false), Loc(l) {
assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
+ setValue(C, V);
}
- /// \brief Construct an empty integer literal.
- explicit IntegerLiteral(EmptyShell Empty)
- : Expr(IntegerLiteralClass, Empty) { }
+ // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
+ // or UnsignedLongLongTy
+ static IntegerLiteral *Create(ASTContext &C, const llvm::APInt &V,
+ QualType type, SourceLocation l);
+ static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty);
- const llvm::APInt &getValue() const { return Value; }
+ llvm::APInt getValue() const { return Num.getValue(); }
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
/// \brief Retrieve the location of the literal.
SourceLocation getLocation() const { return Loc; }
- void setValue(const llvm::APInt &Val) { Value = Val; }
+ void setValue(ASTContext &C, const llvm::APInt &Val) { Num.setValue(C, Val); }
void setLocation(SourceLocation Location) { Loc = Location; }
static bool classof(const Stmt *T) {
@@ -795,21 +883,30 @@ public:
};
class FloatingLiteral : public Expr {
- llvm::APFloat Value;
+ APFloatStorage Num;
bool IsExact : 1;
SourceLocation Loc;
-public:
- FloatingLiteral(const llvm::APFloat &V, bool isexact,
+
+ FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact,
QualType Type, SourceLocation L)
- : Expr(FloatingLiteralClass, Type, false, false), Value(V),
- IsExact(isexact), Loc(L) {}
+ : Expr(FloatingLiteralClass, Type, false, false),
+ IsExact(isexact), Loc(L) {
+ setValue(C, V);
+ }
/// \brief Construct an empty floating-point literal.
explicit FloatingLiteral(EmptyShell Empty)
- : Expr(FloatingLiteralClass, Empty), Value(0.0) { }
+ : Expr(FloatingLiteralClass, Empty), IsExact(false) { }
- const llvm::APFloat &getValue() const { return Value; }
- void setValue(const llvm::APFloat &Val) { Value = Val; }
+public:
+ static FloatingLiteral *Create(ASTContext &C, const llvm::APFloat &V,
+ bool isexact, QualType Type, SourceLocation L);
+ static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty);
+
+ llvm::APFloat getValue() const { return Num.getValue(); }
+ void setValue(ASTContext &C, const llvm::APFloat &Val) {
+ Num.setValue(C, Val);
+ }
bool isExact() const { return IsExact; }
void setExact(bool E) { IsExact = E; }
@@ -889,9 +986,6 @@ class StringLiteral : public Expr {
StringLiteral(QualType Ty) : Expr(StringLiteralClass, Ty, false, false) {}
-protected:
- virtual void DoDestroy(ASTContext &C);
-
public:
/// This is the "fully general" constructor that allows representation of
/// strings formed from multiple concatenated tokens.
@@ -912,8 +1006,7 @@ public:
llvm::StringRef getString() const {
return llvm::StringRef(StrData, ByteLength);
}
- // FIXME: These are deprecated, replace with StringRef.
- const char *getStrData() const { return StrData; }
+
unsigned getByteLength() const { return ByteLength; }
/// \brief Sets the string data to the given string data.
@@ -1009,40 +1102,27 @@ public:
/// applied to a non-complex value, the former returns its operand and the
/// later returns zero in the type of the operand.
///
-/// __builtin_offsetof(type, a.b[10]) is represented as a unary operator whose
-/// subexpression is a compound literal with the various MemberExpr and
-/// ArraySubscriptExpr's applied to it. (This is only used in C)
-///
class UnaryOperator : public Expr {
public:
- // Note that additions to this should also update the StmtVisitor class.
- enum Opcode {
- PostInc, PostDec, // [C99 6.5.2.4] Postfix increment and decrement operators
- PreInc, PreDec, // [C99 6.5.3.1] Prefix increment and decrement operators.
- AddrOf, Deref, // [C99 6.5.3.2] Address and indirection operators.
- Plus, Minus, // [C99 6.5.3.3] Unary arithmetic operators.
- Not, LNot, // [C99 6.5.3.3] Unary arithmetic operators.
- Real, Imag, // "__real expr"/"__imag expr" Extension.
- Extension, // __extension__ marker.
- OffsetOf // __builtin_offsetof
- };
+ typedef UnaryOperatorKind Opcode;
+
private:
- Stmt *Val;
- Opcode Opc;
+ unsigned Opc : 5;
SourceLocation Loc;
+ Stmt *Val;
public:
UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
: Expr(UnaryOperatorClass, type,
- input->isTypeDependent() && opc != OffsetOf,
+ input->isTypeDependent() || type->isDependentType(),
input->isValueDependent()),
- Val(input), Opc(opc), Loc(l) {}
+ Opc(opc), Loc(l), Val(input) {}
/// \brief Build an empty unary operator.
explicit UnaryOperator(EmptyShell Empty)
- : Expr(UnaryOperatorClass, Empty), Opc(AddrOf) { }
+ : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { }
- Opcode getOpcode() const { return Opc; }
+ Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
void setOpcode(Opcode O) { Opc = O; }
Expr *getSubExpr() const { return cast<Expr>(Val); }
@@ -1054,21 +1134,26 @@ public:
/// isPostfix - Return true if this is a postfix operation, like x++.
static bool isPostfix(Opcode Op) {
- return Op == PostInc || Op == PostDec;
+ return Op == UO_PostInc || Op == UO_PostDec;
}
/// isPostfix - Return true if this is a prefix operation, like --x.
static bool isPrefix(Opcode Op) {
- return Op == PreInc || Op == PreDec;
+ return Op == UO_PreInc || Op == UO_PreDec;
}
- bool isPrefix() const { return isPrefix(Opc); }
- bool isPostfix() const { return isPostfix(Opc); }
- bool isIncrementOp() const {return Opc==PreInc || Opc==PostInc; }
- bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; }
- bool isOffsetOfOp() const { return Opc == OffsetOf; }
- static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; }
- bool isArithmeticOp() const { return isArithmeticOp(Opc); }
+ bool isPrefix() const { return isPrefix(getOpcode()); }
+ bool isPostfix() const { return isPostfix(getOpcode()); }
+ bool isIncrementOp() const {
+ return Opc == UO_PreInc || Opc == UO_PostInc;
+ }
+ bool isIncrementDecrementOp() const {
+ return Opc <= UO_PreDec;
+ }
+ static bool isArithmeticOp(Opcode Op) {
+ return Op >= UO_Plus && Op <= UO_LNot;
+ }
+ bool isArithmeticOp() const { return isArithmeticOp(getOpcode()); }
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
/// corresponds to, e.g. "sizeof" or "[pre]++"
@@ -1310,9 +1395,6 @@ class SizeOfAlignOfExpr : public Expr {
} Argument;
SourceLocation OpLoc, RParenLoc;
-protected:
- virtual void DoDestroy(ASTContext& C);
-
public:
SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo,
QualType resultType, SourceLocation op,
@@ -1485,8 +1567,6 @@ protected:
CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, unsigned numargs,
QualType t, SourceLocation rparenloc);
- virtual void DoDestroy(ASTContext& C);
-
public:
CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t,
SourceLocation rparenloc);
@@ -1494,8 +1574,6 @@ public:
/// \brief Build an empty call expression.
CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty);
- ~CallExpr() {}
-
const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
void setCallee(Expr *F) { SubExprs[FN] = F; }
@@ -1594,6 +1672,10 @@ class MemberExpr : public Expr {
/// MemberLoc - This is the location of the member name.
SourceLocation MemberLoc;
+ /// MemberDNLoc - Provides source/type location info for the
+ /// declaration name embedded in MemberDecl.
+ DeclarationNameLoc MemberDNLoc;
+
/// IsArrow - True if this is "X->F", false if this is "X.F".
bool IsArrow : 1;
@@ -1621,37 +1703,33 @@ class MemberExpr : public Expr {
return const_cast<MemberExpr *>(this)->getMemberQualifier();
}
- /// \brief Retrieve the explicit template argument list that followed the
- /// member template name, if any.
- ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
- if (!HasExplicitTemplateArgumentList)
- return 0;
-
- if (!HasQualifierOrFoundDecl)
- return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
-
- return reinterpret_cast<ExplicitTemplateArgumentList *>(
- getMemberQualifier() + 1);
- }
-
- /// \brief Retrieve the explicit template argument list that followed the
- /// member template name, if any.
- const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
- return const_cast<MemberExpr *>(this)->getExplicitTemplateArgumentList();
+public:
+ MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl,
+ const DeclarationNameInfo &NameInfo, QualType ty)
+ : Expr(MemberExprClass, ty,
+ base->isTypeDependent(), base->isValueDependent()),
+ Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()),
+ MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow),
+ HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {
+ assert(memberdecl->getDeclName() == NameInfo.getName());
}
-public:
+ // NOTE: this constructor should be used only when it is known that
+ // the member name can not provide additional syntactic info
+ // (i.e., source locations for C++ operator names or type source info
+ // for constructors, destructors and conversion oeprators).
MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl,
SourceLocation l, QualType ty)
: Expr(MemberExprClass, ty,
base->isTypeDependent(), base->isValueDependent()),
- Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow),
+ Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(),
+ IsArrow(isarrow),
HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {}
static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
NestedNameSpecifier *qual, SourceRange qualrange,
ValueDecl *memberdecl, DeclAccessPair founddecl,
- SourceLocation l,
+ DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *targs,
QualType ty);
@@ -1700,15 +1778,42 @@ public:
/// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgumentList() const {
+ bool hasExplicitTemplateArgs() const {
return HasExplicitTemplateArgumentList;
}
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgumentList())
- getExplicitTemplateArgumentList()->copyInto(List);
+ if (hasExplicitTemplateArgs())
+ getExplicitTemplateArgs().copyInto(List);
+ }
+
+ /// \brief Retrieve the explicit template argument list that
+ /// follow the member template name. This must only be called on an
+ /// expression with explicit template arguments.
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+ assert(HasExplicitTemplateArgumentList);
+ if (!HasQualifierOrFoundDecl)
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(
+ getMemberQualifier() + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that
+ /// followed the member template name. This must only be called on
+ /// an expression with explicit template arguments.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ return const_cast<MemberExpr *>(this)->getExplicitTemplateArgs();
+ }
+
+ /// \brief Retrieves the optional explicit template arguments.
+ /// This points to the same data as getExplicitTemplateArgs(), but
+ /// returns null if there are no explicit template arguments.
+ const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() const {
+ if (!hasExplicitTemplateArgs()) return 0;
+ return &getExplicitTemplateArgs();
}
/// \brief Retrieve the location of the left angle bracket following the
@@ -1717,7 +1822,7 @@ public:
if (!HasExplicitTemplateArgumentList)
return SourceLocation();
- return getExplicitTemplateArgumentList()->LAngleLoc;
+ return getExplicitTemplateArgs().LAngleLoc;
}
/// \brief Retrieve the template arguments provided as part of this
@@ -1726,7 +1831,7 @@ public:
if (!HasExplicitTemplateArgumentList)
return 0;
- return getExplicitTemplateArgumentList()->getTemplateArgs();
+ return getExplicitTemplateArgs().getTemplateArgs();
}
/// \brief Retrieve the number of template arguments provided as part of this
@@ -1735,7 +1840,7 @@ public:
if (!HasExplicitTemplateArgumentList)
return 0;
- return getExplicitTemplateArgumentList()->NumTemplateArgs;
+ return getExplicitTemplateArgs().NumTemplateArgs;
}
/// \brief Retrieve the location of the right angle bracket following the
@@ -1744,7 +1849,13 @@ public:
if (!HasExplicitTemplateArgumentList)
return SourceLocation();
- return getExplicitTemplateArgumentList()->RAngleLoc;
+ return getExplicitTemplateArgs().RAngleLoc;
+ }
+
+ /// \brief Retrieve the member declaration name info.
+ DeclarationNameInfo getMemberNameInfo() const {
+ return DeclarationNameInfo(MemberDecl->getDeclName(),
+ MemberLoc, MemberDNLoc);
}
bool isArrow() const { return IsArrow; }
@@ -1758,9 +1869,8 @@ public:
virtual SourceRange getSourceRange() const {
// If we have an implicit base (like a C++ implicit this),
// make sure not to return its location
- SourceLocation EndLoc = MemberLoc;
- if (HasExplicitTemplateArgumentList)
- EndLoc = getRAngleLoc();
+ SourceLocation EndLoc = (HasExplicitTemplateArgumentList)
+ ? getRAngleLoc() : getMemberNameInfo().getEndLoc();
SourceLocation BaseLoc = getBase()->getLocStart();
if (BaseLoc.isInvalid())
@@ -1843,110 +1953,13 @@ public:
/// classes).
class CastExpr : public Expr {
public:
- /// CastKind - the kind of cast this represents.
- enum CastKind {
- /// CK_Unknown - Unknown cast kind.
- /// FIXME: The goal is to get rid of this and make all casts have a
- /// kind so that the AST client doesn't have to try to figure out what's
- /// going on.
- CK_Unknown,
-
- /// CK_BitCast - Used for reinterpret_cast.
- CK_BitCast,
-
- /// CK_LValueBitCast - Used for reinterpret_cast of expressions to
- /// a reference type.
- CK_LValueBitCast,
-
- /// CK_NoOp - Used for const_cast.
- CK_NoOp,
-
- /// CK_BaseToDerived - Base to derived class casts.
- CK_BaseToDerived,
-
- /// CK_DerivedToBase - Derived to base class casts.
- CK_DerivedToBase,
-
- /// CK_UncheckedDerivedToBase - Derived to base class casts that
- /// assume that the derived pointer is not null.
- CK_UncheckedDerivedToBase,
-
- /// CK_Dynamic - Dynamic cast.
- CK_Dynamic,
-
- /// CK_ToUnion - Cast to union (GCC extension).
- CK_ToUnion,
-
- /// CK_ArrayToPointerDecay - Array to pointer decay.
- CK_ArrayToPointerDecay,
-
- // CK_FunctionToPointerDecay - Function to pointer decay.
- CK_FunctionToPointerDecay,
-
- /// CK_NullToMemberPointer - Null pointer to member pointer.
- CK_NullToMemberPointer,
-
- /// CK_BaseToDerivedMemberPointer - Member pointer in base class to
- /// member pointer in derived class.
- CK_BaseToDerivedMemberPointer,
-
- /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to
- /// member pointer in base class.
- CK_DerivedToBaseMemberPointer,
-
- /// CK_UserDefinedConversion - Conversion using a user defined type
- /// conversion function.
- CK_UserDefinedConversion,
-
- /// CK_ConstructorConversion - Conversion by constructor
- CK_ConstructorConversion,
-
- /// CK_IntegralToPointer - Integral to pointer
- CK_IntegralToPointer,
-
- /// CK_PointerToIntegral - Pointer to integral
- CK_PointerToIntegral,
-
- /// CK_ToVoid - Cast to void.
- CK_ToVoid,
-
- /// CK_VectorSplat - Casting from an integer/floating type to an extended
- /// vector type with the same element type as the src type. Splats the
- /// src expression into the destination expression.
- CK_VectorSplat,
-
- /// CK_IntegralCast - Casting between integral types of different size.
- CK_IntegralCast,
-
- /// CK_IntegralToFloating - Integral to floating point.
- CK_IntegralToFloating,
-
- /// CK_FloatingToIntegral - Floating point to integral.
- CK_FloatingToIntegral,
-
- /// CK_FloatingCast - Casting between floating types of different size.
- CK_FloatingCast,
-
- /// CK_MemberPointerToBoolean - Member pointer to boolean
- CK_MemberPointerToBoolean,
-
- /// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c
- /// pointer
- CK_AnyPointerToObjCPointerCast,
- /// CK_AnyPointerToBlockPointerCast - Casting any pointer to block
- /// pointer
- CK_AnyPointerToBlockPointerCast
-
- };
+ typedef clang::CastKind CastKind;
private:
- CastKind Kind;
+ unsigned Kind : 5;
+ unsigned BasePathSize : BitsRemaining - 5;
Stmt *Op;
- /// BasePath - For derived-to-base and base-to-derived casts, the base array
- /// contains the inheritance path.
- CXXBaseSpecifierArray BasePath;
-
void CheckBasePath() const {
#ifndef NDEBUG
switch (getCastKind()) {
@@ -1955,7 +1968,7 @@ private:
case CK_DerivedToBaseMemberPointer:
case CK_BaseToDerived:
case CK_BaseToDerivedMemberPointer:
- assert(!BasePath.empty() && "Cast kind should have a base path!");
+ assert(!path_empty() && "Cast kind should have a base path!");
break;
// These should not have an inheritance path.
@@ -1981,15 +1994,21 @@ private:
case CK_MemberPointerToBoolean:
case CK_AnyPointerToObjCPointerCast:
case CK_AnyPointerToBlockPointerCast:
- assert(BasePath.empty() && "Cast kind should not have a base path!");
+ case CK_ObjCObjectLValueCast:
+ assert(path_empty() && "Cast kind should not have a base path!");
break;
}
#endif
}
+ const CXXBaseSpecifier * const *path_buffer() const {
+ return const_cast<CastExpr*>(this)->path_buffer();
+ }
+ CXXBaseSpecifier **path_buffer();
+
protected:
CastExpr(StmtClass SC, QualType ty, const CastKind kind, Expr *op,
- CXXBaseSpecifierArray BasePath) :
+ unsigned BasePathSize) :
Expr(SC, ty,
// Cast expressions are type-dependent if the type is
// dependent (C++ [temp.dep.expr]p3).
@@ -1997,18 +2016,16 @@ protected:
// Cast expressions are value-dependent if the type is
// dependent or if the subexpression is value-dependent.
ty->isDependentType() || (op && op->isValueDependent())),
- Kind(kind), Op(op), BasePath(BasePath) {
- CheckBasePath();
- }
+ Kind(kind), BasePathSize(BasePathSize), Op(op) {
+ CheckBasePath();
+ }
/// \brief Construct an empty cast.
- CastExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty) { }
-
- virtual void DoDestroy(ASTContext &C);
+ CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
+ : Expr(SC, Empty), BasePathSize(BasePathSize) { }
public:
- CastKind getCastKind() const { return Kind; }
+ CastKind getCastKind() const { return static_cast<CastKind>(Kind); }
void setCastKind(CastKind K) { Kind = K; }
const char *getCastKindName() const;
@@ -2024,8 +2041,16 @@ public:
return const_cast<CastExpr *>(this)->getSubExprAsWritten();
}
- const CXXBaseSpecifierArray& getBasePath() const { return BasePath; }
- CXXBaseSpecifierArray& getBasePath() { return BasePath; }
+ typedef CXXBaseSpecifier **path_iterator;
+ typedef const CXXBaseSpecifier * const *path_const_iterator;
+ bool path_empty() const { return BasePathSize == 0; }
+ unsigned path_size() const { return BasePathSize; }
+ path_iterator path_begin() { return path_buffer(); }
+ path_iterator path_end() { return path_buffer() + path_size(); }
+ path_const_iterator path_begin() const { return path_buffer(); }
+ path_const_iterator path_end() const { return path_buffer() + path_size(); }
+
+ void setCastPath(const CXXCastPath &Path);
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstCastExprConstant &&
@@ -2045,38 +2070,57 @@ public:
///
/// In C, implicit casts always produce rvalues. However, in C++, an
/// implicit cast whose result is being bound to a reference will be
-/// an lvalue. For example:
+/// an lvalue or xvalue. For example:
///
/// @code
/// class Base { };
/// class Derived : public Base { };
+/// Derived &&ref();
/// void f(Derived d) {
-/// Base& b = d; // initializer is an ImplicitCastExpr to an lvalue of type Base
+/// Base& b = d; // initializer is an ImplicitCastExpr
+/// // to an lvalue of type Base
+/// Base&& r = ref(); // initializer is an ImplicitCastExpr
+/// // to an xvalue of type Base
/// }
/// @endcode
class ImplicitCastExpr : public CastExpr {
- /// LvalueCast - Whether this cast produces an lvalue.
- bool LvalueCast;
+private:
+ ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
+ unsigned BasePathLength, ExprValueKind VK)
+ : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePathLength) {
+ ValueKind = VK;
+ }
+
+ /// \brief Construct an empty implicit cast.
+ explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
+ : CastExpr(ImplicitCastExprClass, Shell, PathSize) { }
public:
- ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
- CXXBaseSpecifierArray BasePath, bool Lvalue)
- : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePath),
- LvalueCast(Lvalue) { }
+ enum OnStack_t { OnStack };
+ ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op,
+ ExprValueKind VK)
+ : CastExpr(ImplicitCastExprClass, ty, kind, op, 0) {
+ ValueKind = VK;
+ }
- /// \brief Construct an empty implicit cast.
- explicit ImplicitCastExpr(EmptyShell Shell)
- : CastExpr(ImplicitCastExprClass, Shell) { }
+ static ImplicitCastExpr *Create(ASTContext &Context, QualType T,
+ CastKind Kind, Expr *Operand,
+ const CXXCastPath *BasePath,
+ ExprValueKind Cat);
+
+ static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize);
virtual SourceRange getSourceRange() const {
return getSubExpr()->getSourceRange();
}
- /// isLvalueCast - Whether this cast produces an lvalue.
- bool isLvalueCast() const { return LvalueCast; }
+ /// getValueKind - The value kind that this cast produces.
+ ExprValueKind getValueKind() const {
+ return static_cast<ExprValueKind>(ValueKind);
+ }
- /// setLvalueCast - Set whether this cast produces an lvalue.
- void setLvalueCast(bool Lvalue) { LvalueCast = Lvalue; }
+ /// setValueKind - Set the value kind this cast produces.
+ void setValueKind(ExprValueKind Cat) { ValueKind = Cat; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImplicitCastExprClass;
@@ -2098,8 +2142,8 @@ public:
/// actual type of the expression as determined by semantic
/// analysis. These types may differ slightly. For example, in C++ one
/// can cast to a reference type, which indicates that the resulting
-/// expression will be an lvalue. The reference type, however, will
-/// not be used as the type of the expression.
+/// expression will be an lvalue or xvalue. The reference type, however,
+/// will not be used as the type of the expression.
class ExplicitCastExpr : public CastExpr {
/// TInfo - Source type info for the (written) type
/// this expression is casting to.
@@ -2107,13 +2151,12 @@ class ExplicitCastExpr : public CastExpr {
protected:
ExplicitCastExpr(StmtClass SC, QualType exprTy, CastKind kind,
- Expr *op, CXXBaseSpecifierArray BasePath,
- TypeSourceInfo *writtenTy)
- : CastExpr(SC, exprTy, kind, op, BasePath), TInfo(writtenTy) {}
+ Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy)
+ : CastExpr(SC, exprTy, kind, op, PathSize), TInfo(writtenTy) {}
/// \brief Construct an empty explicit cast.
- ExplicitCastExpr(StmtClass SC, EmptyShell Shell)
- : CastExpr(SC, Shell) { }
+ ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
+ : CastExpr(SC, Shell, PathSize) { }
public:
/// getTypeInfoAsWritten - Returns the type source info for the type
@@ -2138,16 +2181,24 @@ public:
class CStyleCastExpr : public ExplicitCastExpr {
SourceLocation LPLoc; // the location of the left paren
SourceLocation RPLoc; // the location of the right paren
-public:
+
CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op,
- CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ unsigned PathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation r)
- : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, BasePath,
+ : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, PathSize,
writtenTy), LPLoc(l), RPLoc(r) {}
/// \brief Construct an empty C-style explicit cast.
- explicit CStyleCastExpr(EmptyShell Shell)
- : ExplicitCastExpr(CStyleCastExprClass, Shell) { }
+ explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
+ : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
+
+public:
+ static CStyleCastExpr *Create(ASTContext &Context, QualType T, CastKind K,
+ Expr *Op, const CXXCastPath *BasePath,
+ TypeSourceInfo *WrittenTy, SourceLocation L,
+ SourceLocation R);
+
+ static CStyleCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize);
SourceLocation getLParenLoc() const { return LPLoc; }
void setLParenLoc(SourceLocation L) { LPLoc = L; }
@@ -2184,33 +2235,14 @@ public:
/// be used to express the computation.
class BinaryOperator : public Expr {
public:
- enum Opcode {
- // Operators listed in order of precedence.
- // Note that additions to this should also update the StmtVisitor class.
- PtrMemD, PtrMemI, // [C++ 5.5] Pointer-to-member operators.
- Mul, Div, Rem, // [C99 6.5.5] Multiplicative operators.
- Add, Sub, // [C99 6.5.6] Additive operators.
- Shl, Shr, // [C99 6.5.7] Bitwise shift operators.
- LT, GT, LE, GE, // [C99 6.5.8] Relational operators.
- EQ, NE, // [C99 6.5.9] Equality operators.
- And, // [C99 6.5.10] Bitwise AND operator.
- Xor, // [C99 6.5.11] Bitwise XOR operator.
- Or, // [C99 6.5.12] Bitwise OR operator.
- LAnd, // [C99 6.5.13] Logical AND operator.
- LOr, // [C99 6.5.14] Logical OR operator.
- Assign, MulAssign,// [C99 6.5.16] Assignment operators.
- DivAssign, RemAssign,
- AddAssign, SubAssign,
- ShlAssign, ShrAssign,
- AndAssign, XorAssign,
- OrAssign,
- Comma // [C99 6.5.17] Comma operator.
- };
+ typedef BinaryOperatorKind Opcode;
+
private:
+ unsigned Opc : 6;
+ SourceLocation OpLoc;
+
enum { LHS, RHS, END_EXPR };
Stmt* SubExprs[END_EXPR];
- Opcode Opc;
- SourceLocation OpLoc;
public:
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
@@ -2227,12 +2259,12 @@ public:
/// \brief Construct an empty binary operator.
explicit BinaryOperator(EmptyShell Empty)
- : Expr(BinaryOperatorClass, Empty), Opc(Comma) { }
+ : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { }
SourceLocation getOperatorLoc() const { return OpLoc; }
void setOperatorLoc(SourceLocation L) { OpLoc = L; }
- Opcode getOpcode() const { return Opc; }
+ Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
void setOpcode(Opcode O) { Opc = O; }
Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
@@ -2248,6 +2280,8 @@ public:
/// corresponds to, e.g. "<<=".
static const char *getOpcodeStr(Opcode Op);
+ const char *getOpcodeStr() const { return getOpcodeStr(getOpcode()); }
+
/// \brief Retrieve the binary opcode that corresponds to the given
/// overloaded operator.
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO);
@@ -2257,30 +2291,34 @@ public:
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
/// predicates to categorize the respective opcodes.
- bool isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; }
- static bool isAdditiveOp(Opcode Opc) { return Opc == Add || Opc == Sub; }
- bool isAdditiveOp() const { return isAdditiveOp(Opc); }
- static bool isShiftOp(Opcode Opc) { return Opc == Shl || Opc == Shr; }
- bool isShiftOp() const { return isShiftOp(Opc); }
+ bool isMultiplicativeOp() const { return Opc >= BO_Mul && Opc <= BO_Rem; }
+ static bool isAdditiveOp(Opcode Opc) { return Opc == BO_Add || Opc==BO_Sub; }
+ bool isAdditiveOp() const { return isAdditiveOp(getOpcode()); }
+ static bool isShiftOp(Opcode Opc) { return Opc == BO_Shl || Opc == BO_Shr; }
+ bool isShiftOp() const { return isShiftOp(getOpcode()); }
- static bool isBitwiseOp(Opcode Opc) { return Opc >= And && Opc <= Or; }
- bool isBitwiseOp() const { return isBitwiseOp(Opc); }
+ static bool isBitwiseOp(Opcode Opc) { return Opc >= BO_And && Opc <= BO_Or; }
+ bool isBitwiseOp() const { return isBitwiseOp(getOpcode()); }
- static bool isRelationalOp(Opcode Opc) { return Opc >= LT && Opc <= GE; }
- bool isRelationalOp() const { return isRelationalOp(Opc); }
+ static bool isRelationalOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_GE; }
+ bool isRelationalOp() const { return isRelationalOp(getOpcode()); }
- static bool isEqualityOp(Opcode Opc) { return Opc == EQ || Opc == NE; }
- bool isEqualityOp() const { return isEqualityOp(Opc); }
+ static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; }
+ bool isEqualityOp() const { return isEqualityOp(getOpcode()); }
- static bool isComparisonOp(Opcode Opc) { return Opc >= LT && Opc <= NE; }
- bool isComparisonOp() const { return isComparisonOp(Opc); }
+ static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; }
+ bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
- static bool isLogicalOp(Opcode Opc) { return Opc == LAnd || Opc == LOr; }
- bool isLogicalOp() const { return isLogicalOp(Opc); }
+ static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; }
+ bool isLogicalOp() const { return isLogicalOp(getOpcode()); }
- bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; }
- bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;}
- bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; }
+ bool isAssignmentOp() const { return Opc >= BO_Assign && Opc <= BO_OrAssign; }
+ bool isCompoundAssignmentOp() const {
+ return Opc > BO_Assign && Opc <= BO_OrAssign;
+ }
+ bool isShiftAssignOp() const {
+ return Opc == BO_ShlAssign || Opc == BO_ShrAssign;
+ }
static bool classof(const Stmt *S) {
return S->getStmtClass() >= firstBinaryOperatorConstant &&
@@ -2304,7 +2342,7 @@ protected:
}
BinaryOperator(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Opc(MulAssign) { }
+ : Expr(SC, Empty), Opc(BO_MulAssign) { }
};
/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
@@ -2353,10 +2391,11 @@ public:
class ConditionalOperator : public Expr {
enum { COND, LHS, RHS, END_EXPR };
Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
+ Stmt* Save;
SourceLocation QuestionLoc, ColonLoc;
public:
ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs,
- SourceLocation CLoc, Expr *rhs, QualType t)
+ SourceLocation CLoc, Expr *rhs, Expr *save, QualType t)
: Expr(ConditionalOperatorClass, t,
// FIXME: the type of the conditional operator doesn't
// depend on the type of the conditional, but the standard
@@ -2370,6 +2409,7 @@ public:
SubExprs[COND] = cond;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
+ Save = save;
}
/// \brief Build an empty conditional operator.
@@ -2382,25 +2422,31 @@ public:
void setCond(Expr *E) { SubExprs[COND] = E; }
// getTrueExpr - Return the subexpression representing the value of the ?:
- // expression if the condition evaluates to true. In most cases this value
- // will be the same as getLHS() except a GCC extension allows the left
- // subexpression to be omitted, and instead of the condition be returned.
- // e.g: x ?: y is shorthand for x ? x : y, except that the expression "x"
- // is only evaluated once.
+ // expression if the condition evaluates to true.
Expr *getTrueExpr() const {
- return cast<Expr>(SubExprs[LHS] ? SubExprs[LHS] : SubExprs[COND]);
+ return cast<Expr>(!Save ? SubExprs[LHS] : SubExprs[COND]);
}
- // getTrueExpr - Return the subexpression representing the value of the ?:
+ // getFalseExpr - Return the subexpression representing the value of the ?:
// expression if the condition evaluates to false. This is the same as getRHS.
Expr *getFalseExpr() const { return cast<Expr>(SubExprs[RHS]); }
-
- Expr *getLHS() const { return cast_or_null<Expr>(SubExprs[LHS]); }
+
+ // getSaveExpr - In most cases this value will be null. Except a GCC extension
+ // allows the left subexpression to be omitted, and instead of that condition
+ // be returned. e.g: x ?: y is shorthand for x ? x : y, except that the
+ // expression "x" is only evaluated once. Under this senario, this function
+ // returns the original, non-converted condition expression for the ?:operator
+ Expr *getSaveExpr() const { return Save? cast<Expr>(Save) : (Expr*)0; }
+
+ Expr *getLHS() const { return Save ? 0 : cast<Expr>(SubExprs[LHS]); }
void setLHS(Expr *E) { SubExprs[LHS] = E; }
Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
void setRHS(Expr *E) { SubExprs[RHS] = E; }
+ Expr *getSAVE() const { return Save? cast<Expr>(Save) : (Expr*)0; }
+ void setSAVE(Expr *E) { Save = E; }
+
SourceLocation getQuestionLoc() const { return QuestionLoc; }
void setQuestionLoc(SourceLocation L) { QuestionLoc = L; }
@@ -2500,23 +2546,27 @@ public:
/// expressions) are compatible. The result of this built-in function can be
/// used in integer constant expressions.
class TypesCompatibleExpr : public Expr {
- QualType Type1;
- QualType Type2;
+ TypeSourceInfo *TInfo1;
+ TypeSourceInfo *TInfo2;
SourceLocation BuiltinLoc, RParenLoc;
public:
TypesCompatibleExpr(QualType ReturnType, SourceLocation BLoc,
- QualType t1, QualType t2, SourceLocation RP) :
+ TypeSourceInfo *tinfo1, TypeSourceInfo *tinfo2,
+ SourceLocation RP) :
Expr(TypesCompatibleExprClass, ReturnType, false, false),
- Type1(t1), Type2(t2), BuiltinLoc(BLoc), RParenLoc(RP) {}
+ TInfo1(tinfo1), TInfo2(tinfo2), BuiltinLoc(BLoc), RParenLoc(RP) {}
/// \brief Build an empty __builtin_type_compatible_p expression.
explicit TypesCompatibleExpr(EmptyShell Empty)
: Expr(TypesCompatibleExprClass, Empty) { }
- QualType getArgType1() const { return Type1; }
- void setArgType1(QualType T) { Type1 = T; }
- QualType getArgType2() const { return Type2; }
- void setArgType2(QualType T) { Type2 = T; }
+ TypeSourceInfo *getArgTInfo1() const { return TInfo1; }
+ void setArgTInfo1(TypeSourceInfo *TInfo) { TInfo1 = TInfo; }
+ TypeSourceInfo *getArgTInfo2() const { return TInfo2; }
+ void setArgTInfo2(TypeSourceInfo *TInfo) { TInfo2 = TInfo; }
+
+ QualType getArgType1() const { return TInfo1->getType(); }
+ QualType getArgType2() const { return TInfo2->getType(); }
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
@@ -2553,9 +2603,6 @@ class ShuffleVectorExpr : public Expr {
Stmt **SubExprs;
unsigned NumExprs;
-protected:
- virtual void DoDestroy(ASTContext &C);
-
public:
// FIXME: Can a shufflevector be value-dependent? Does type-dependence need
// to be computed differently?
@@ -2588,8 +2635,6 @@ public:
}
static bool classof(const ShuffleVectorExpr *) { return true; }
- ~ShuffleVectorExpr() {}
-
/// getNumSubExprs - Return the size of the SubExprs array. This includes the
/// constant expression, the actual arguments passed in, and the function
/// pointers.
@@ -2716,11 +2761,13 @@ public:
/// VAArgExpr, used for the builtin function __builtin_va_arg.
class VAArgExpr : public Expr {
Stmt *Val;
+ TypeSourceInfo *TInfo;
SourceLocation BuiltinLoc, RParenLoc;
public:
- VAArgExpr(SourceLocation BLoc, Expr* e, QualType t, SourceLocation RPLoc)
+ VAArgExpr(SourceLocation BLoc, Expr* e, TypeSourceInfo *TInfo,
+ SourceLocation RPLoc, QualType t)
: Expr(VAArgExprClass, t, t->isDependentType(), false),
- Val(e),
+ Val(e), TInfo(TInfo),
BuiltinLoc(BLoc),
RParenLoc(RPLoc) { }
@@ -2731,6 +2778,9 @@ public:
Expr *getSubExpr() { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
+ TypeSourceInfo *getWrittenTypeInfo() const { return TInfo; }
+ void setWrittenTypeInfo(TypeSourceInfo *TI) { TInfo = TI; }
+
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
@@ -2896,12 +2946,18 @@ public:
virtual child_iterator child_end();
typedef InitExprsTy::iterator iterator;
+ typedef InitExprsTy::const_iterator const_iterator;
typedef InitExprsTy::reverse_iterator reverse_iterator;
+ typedef InitExprsTy::const_reverse_iterator const_reverse_iterator;
iterator begin() { return InitExprs.begin(); }
+ const_iterator begin() const { return InitExprs.begin(); }
iterator end() { return InitExprs.end(); }
+ const_iterator end() const { return InitExprs.end(); }
reverse_iterator rbegin() { return InitExprs.rbegin(); }
+ const_reverse_iterator rbegin() const { return InitExprs.rbegin(); }
reverse_iterator rend() { return InitExprs.rend(); }
+ const_reverse_iterator rend() const { return InitExprs.rend(); }
};
/// @brief Represents a C99 designated initializer expression.
@@ -2961,11 +3017,6 @@ private:
: Expr(DesignatedInitExprClass, EmptyShell()),
NumDesignators(0), Designators(0), NumSubExprs(NumSubExprs) { }
-protected:
- virtual void DoDestroy(ASTContext &C);
-
- void DestroyDesignators(ASTContext &C);
-
public:
/// A field designator, e.g., ".x".
struct FieldDesignator {
@@ -3233,15 +3284,10 @@ class ParenListExpr : public Expr {
unsigned NumExprs;
SourceLocation LParenLoc, RParenLoc;
-protected:
- virtual void DoDestroy(ASTContext& C);
-
public:
ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs,
unsigned numexprs, SourceLocation rparenloc);
- ~ParenListExpr() {}
-
/// \brief Build an empty paren list.
explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
@@ -3274,8 +3320,8 @@ public:
virtual child_iterator child_begin();
virtual child_iterator child_end();
- friend class PCHStmtReader;
- friend class PCHStmtWriter;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
};
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index b955381..0a94354 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -121,12 +121,12 @@ private:
protected:
CXXNamedCastExpr(StmtClass SC, QualType ty, CastKind kind, Expr *op,
- CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ unsigned PathSize, TypeSourceInfo *writtenTy,
SourceLocation l)
- : ExplicitCastExpr(SC, ty, kind, op, BasePath, writtenTy), Loc(l) {}
+ : ExplicitCastExpr(SC, ty, kind, op, PathSize, writtenTy), Loc(l) {}
- explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell)
- : ExplicitCastExpr(SC, Shell) { }
+ explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
+ : ExplicitCastExpr(SC, Shell, PathSize) { }
public:
const char *getCastName() const;
@@ -158,14 +158,22 @@ public:
/// This expression node represents a C++ static cast, e.g.,
/// @c static_cast<int>(1.0).
class CXXStaticCastExpr : public CXXNamedCastExpr {
-public:
CXXStaticCastExpr(QualType ty, CastKind kind, Expr *op,
- CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l)
- : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, BasePath, writtenTy, l) {}
+ : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, pathSize,
+ writtenTy, l) {}
- explicit CXXStaticCastExpr(EmptyShell Empty)
- : CXXNamedCastExpr(CXXStaticCastExprClass, Empty) { }
+ explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
+ : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { }
+
+public:
+ static CXXStaticCastExpr *Create(ASTContext &Context, QualType T,
+ CastKind K, Expr *Op,
+ const CXXCastPath *Path,
+ TypeSourceInfo *Written, SourceLocation L);
+ static CXXStaticCastExpr *CreateEmpty(ASTContext &Context,
+ unsigned PathSize);
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXStaticCastExprClass;
@@ -180,15 +188,23 @@ public:
/// This expression node represents a dynamic cast, e.g.,
/// @c dynamic_cast<Derived*>(BasePtr).
class CXXDynamicCastExpr : public CXXNamedCastExpr {
-public:
CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op,
- CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, BasePath,
+ : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, pathSize,
writtenTy, l) {}
- explicit CXXDynamicCastExpr(EmptyShell Empty)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty) { }
+ explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
+ : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { }
+
+public:
+ static CXXDynamicCastExpr *Create(ASTContext &Context, QualType T,
+ CastKind Kind, Expr *Op,
+ const CXXCastPath *Path,
+ TypeSourceInfo *Written, SourceLocation L);
+
+ static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context,
+ unsigned pathSize);
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDynamicCastExprClass;
@@ -203,15 +219,22 @@ public:
/// This expression node represents a reinterpret cast, e.g.,
/// @c reinterpret_cast<int>(VoidPtr).
class CXXReinterpretCastExpr : public CXXNamedCastExpr {
-public:
CXXReinterpretCastExpr(QualType ty, CastKind kind, Expr *op,
- CXXBaseSpecifierArray BasePath,
+ unsigned pathSize,
TypeSourceInfo *writtenTy, SourceLocation l)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, BasePath,
+ : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, pathSize,
writtenTy, l) {}
- explicit CXXReinterpretCastExpr(EmptyShell Empty)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty) { }
+ CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
+ : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { }
+
+public:
+ static CXXReinterpretCastExpr *Create(ASTContext &Context, QualType T,
+ CastKind Kind, Expr *Op,
+ const CXXCastPath *Path,
+ TypeSourceInfo *WrittenTy, SourceLocation L);
+ static CXXReinterpretCastExpr *CreateEmpty(ASTContext &Context,
+ unsigned pathSize);
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXReinterpretCastExprClass;
@@ -225,14 +248,18 @@ public:
/// This expression node represents a const cast, e.g.,
/// @c const_cast<char*>(PtrToConstChar).
class CXXConstCastExpr : public CXXNamedCastExpr {
-public:
CXXConstCastExpr(QualType ty, Expr *op, TypeSourceInfo *writtenTy,
SourceLocation l)
: CXXNamedCastExpr(CXXConstCastExprClass, ty, CK_NoOp, op,
- CXXBaseSpecifierArray(), writtenTy, l) {}
+ 0, writtenTy, l) {}
explicit CXXConstCastExpr(EmptyShell Empty)
- : CXXNamedCastExpr(CXXConstCastExprClass, Empty) { }
+ : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { }
+
+public:
+ static CXXConstCastExpr *Create(ASTContext &Context, QualType T, Expr *Op,
+ TypeSourceInfo *WrittenTy, SourceLocation L);
+ static CXXConstCastExpr *CreateEmpty(ASTContext &Context);
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXConstCastExprClass;
@@ -479,9 +506,6 @@ class CXXDefaultArgExpr : public Expr {
*reinterpret_cast<Expr **>(this + 1) = SubExpr;
}
-protected:
- virtual void DoDestroy(ASTContext &C);
-
public:
CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
@@ -535,8 +559,8 @@ public:
virtual child_iterator child_begin();
virtual child_iterator child_end();
- friend class PCHStmtReader;
- friend class PCHStmtWriter;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
};
/// CXXTemporary - Represents a C++ temporary.
@@ -546,14 +570,11 @@ class CXXTemporary {
CXXTemporary(const CXXDestructorDecl *destructor)
: Destructor(destructor) { }
- ~CXXTemporary() { }
public:
static CXXTemporary *Create(ASTContext &C,
const CXXDestructorDecl *Destructor);
- void Destroy(ASTContext &Ctx);
-
const CXXDestructorDecl *getDestructor() const { return Destructor; }
};
@@ -579,10 +600,6 @@ class CXXBindTemporaryExpr : public Expr {
CXXBindTemporaryExpr(CXXTemporary *temp, Expr* subexpr)
: Expr(CXXBindTemporaryExprClass, subexpr->getType(), false, false),
Temp(temp), SubExpr(subexpr) { }
- ~CXXBindTemporaryExpr() { }
-
-protected:
- virtual void DoDestroy(ASTContext &C);
public:
CXXBindTemporaryExpr(EmptyShell Empty)
@@ -614,73 +631,6 @@ public:
virtual child_iterator child_end();
};
-/// CXXBindReferenceExpr - Represents binding an expression to a reference.
-/// In the example:
-///
-/// const int &i = 10;
-///
-/// a bind reference expression is inserted to indicate that 10 is bound to
-/// a reference, and that a temporary needs to be created to hold the
-/// value.
-class CXXBindReferenceExpr : public Expr {
- // SubExpr - The expression being bound.
- Stmt *SubExpr;
-
- // ExtendsLifetime - Whether binding this reference extends the lifetime of
- // the expression being bound. FIXME: Add C++ reference.
- bool ExtendsLifetime;
-
- /// RequiresTemporaryCopy - Whether binding the subexpression requires a
- /// temporary copy.
- bool RequiresTemporaryCopy;
-
- CXXBindReferenceExpr(Expr *subexpr, bool ExtendsLifetime,
- bool RequiresTemporaryCopy)
- : Expr(CXXBindReferenceExprClass, subexpr->getType(), false, false),
- SubExpr(subexpr), ExtendsLifetime(ExtendsLifetime),
- RequiresTemporaryCopy(RequiresTemporaryCopy) { }
- ~CXXBindReferenceExpr() { }
-
-protected:
- virtual void DoDestroy(ASTContext &C);
-
-public:
- static CXXBindReferenceExpr *Create(ASTContext &C, Expr *SubExpr,
- bool ExtendsLifetime,
- bool RequiresTemporaryCopy);
-
- explicit CXXBindReferenceExpr(EmptyShell Empty)
- : Expr(CXXBindReferenceExprClass, Empty) { }
-
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- void setSubExpr(Expr *E) { SubExpr = E; }
-
- virtual SourceRange getSourceRange() const {
- return SubExpr->getSourceRange();
- }
-
- /// requiresTemporaryCopy - Whether binding the subexpression requires a
- /// temporary copy.
- bool requiresTemporaryCopy() const { return RequiresTemporaryCopy; }
-
- // extendsLifetime - Whether binding this reference extends the lifetime of
- // the expression being bound. FIXME: Add C++ reference.
- bool extendsLifetime() const { return ExtendsLifetime; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXBindReferenceExprClass;
- }
- static bool classof(const CXXBindReferenceExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- friend class PCHStmtReader;
-};
-
/// CXXConstructExpr - Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
public:
@@ -707,15 +657,12 @@ protected:
Expr **args, unsigned numargs,
bool ZeroInitialization = false,
ConstructionKind ConstructKind = CK_Complete);
- ~CXXConstructExpr() { }
/// \brief Construct an empty C++ construction expression.
CXXConstructExpr(StmtClass SC, EmptyShell Empty)
: Expr(SC, Empty), Constructor(0), Elidable(0), ZeroInitialization(0),
ConstructKind(0), Args(0), NumArgs(0) { }
- virtual void DoDestroy(ASTContext &C);
-
public:
/// \brief Construct an empty C++ construction expression.
explicit CXXConstructExpr(EmptyShell Empty)
@@ -796,7 +743,7 @@ public:
virtual child_iterator child_begin();
virtual child_iterator child_end();
- friend class PCHStmtReader;
+ friend class ASTStmtReader;
};
/// CXXFunctionalCastExpr - Represents an explicit C++ type conversion
@@ -805,17 +752,27 @@ public:
class CXXFunctionalCastExpr : public ExplicitCastExpr {
SourceLocation TyBeginLoc;
SourceLocation RParenLoc;
-public:
+
CXXFunctionalCastExpr(QualType ty, TypeSourceInfo *writtenTy,
SourceLocation tyBeginLoc, CastKind kind,
- Expr *castExpr, CXXBaseSpecifierArray BasePath,
+ Expr *castExpr, unsigned pathSize,
SourceLocation rParenLoc)
: ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr,
- BasePath, writtenTy),
+ pathSize, writtenTy),
TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
- explicit CXXFunctionalCastExpr(EmptyShell Shell)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell) { }
+ explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
+ : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
+
+public:
+ static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T,
+ TypeSourceInfo *Written,
+ SourceLocation TyBeginLoc,
+ CastKind Kind, Expr *Op,
+ const CXXCastPath *Path,
+ SourceLocation RPLoc);
+ static CXXFunctionalCastExpr *CreateEmpty(ASTContext &Context,
+ unsigned PathSize);
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
@@ -859,8 +816,6 @@ public:
explicit CXXTemporaryObjectExpr(EmptyShell Empty)
: CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) { }
- ~CXXTemporaryObjectExpr() { }
-
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -872,7 +827,7 @@ public:
}
static bool classof(const CXXTemporaryObjectExpr *) { return true; }
- friend class PCHStmtReader;
+ friend class ASTStmtReader;
};
/// CXXScalarValueInitExpr - [C++ 5.2.3p2]
@@ -952,7 +907,7 @@ class CXXNewExpr : public Expr {
SourceLocation StartLoc;
SourceLocation EndLoc;
- friend class PCHStmtReader;
+ friend class ASTStmtReader;
public:
CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
Expr **placementArgs, unsigned numPlaceArgs,
@@ -967,8 +922,6 @@ public:
void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs,
unsigned numConsArgs);
- virtual void DoDestroy(ASTContext &C);
-
QualType getAllocatedType() const {
assert(getType()->isPointerType());
return getType()->getAs<PointerType>()->getPointeeType();
@@ -1381,7 +1334,7 @@ public:
virtual child_iterator child_begin();
virtual child_iterator child_end();
- friend class PCHStmtReader;
+ friend class ASTStmtReader;
};
/// \brief A reference to an overloaded function set, either an
@@ -1395,7 +1348,7 @@ class OverloadExpr : public Expr {
unsigned NumResults;
/// The common name of these declarations.
- DeclarationName Name;
+ DeclarationNameInfo NameInfo;
/// The scope specifier, if any.
NestedNameSpecifier *Qualifier;
@@ -1403,16 +1356,13 @@ class OverloadExpr : public Expr {
/// The source range of the scope specifier.
SourceRange QualifierRange;
- /// The location of the name.
- SourceLocation NameLoc;
-
protected:
/// True if the name was a template-id.
bool HasExplicitTemplateArgs;
OverloadExpr(StmtClass K, ASTContext &C, QualType T, bool Dependent,
NestedNameSpecifier *Qualifier, SourceRange QRange,
- DeclarationName Name, SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
bool HasTemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
@@ -1427,19 +1377,38 @@ public:
UnresolvedSetIterator End,
const TemplateArgumentListInfo *Args);
+ struct FindResult {
+ OverloadExpr *Expression;
+ bool IsAddressOfOperand;
+ bool HasFormOfMemberPointer;
+ };
+
/// Finds the overloaded expression in the given expression of
/// OverloadTy.
///
- /// \return the expression (which must be there) and true if it is
- /// within an address-of operator.
- static llvm::PointerIntPair<OverloadExpr*,1> find(Expr *E) {
+ /// \return the expression (which must be there) and true if it has
+ /// the particular form of a member pointer expression
+ static FindResult find(Expr *E) {
assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
- bool op = false;
+ FindResult Result;
+
E = E->IgnoreParens();
- if (isa<UnaryOperator>(E))
- op = true, E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
- return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(E), op);
+ if (isa<UnaryOperator>(E)) {
+ assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf);
+ E = cast<UnaryOperator>(E)->getSubExpr();
+ OverloadExpr *Ovl = cast<OverloadExpr>(E->IgnoreParens());
+
+ Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier());
+ Result.IsAddressOfOperand = true;
+ Result.Expression = Ovl;
+ } else {
+ Result.HasFormOfMemberPointer = false;
+ Result.IsAddressOfOperand = false;
+ Result.Expression = cast<OverloadExpr>(E);
+ }
+
+ return Result;
}
/// Gets the naming class of this lookup, if any.
@@ -1457,13 +1426,17 @@ public:
/// Gets the number of declarations in the unresolved set.
unsigned getNumDecls() const { return NumResults; }
+ /// 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 Name; }
- void setName(DeclarationName N) { Name = N; }
+ DeclarationName getName() const { return NameInfo.getName(); }
+ void setName(DeclarationName N) { NameInfo.setName(N); }
/// Gets the location of the name.
- SourceLocation getNameLoc() const { return NameLoc; }
- void setNameLoc(SourceLocation Loc) { NameLoc = Loc; }
+ 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; }
@@ -1483,10 +1456,12 @@ public:
return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs();
}
- ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
- if (hasExplicitTemplateArgs())
- return &getExplicitTemplateArgs();
- return 0;
+ /// \brief Retrieves the optional explicit template arguments.
+ /// This points to the same data as getExplicitTemplateArgs(), but
+ /// returns null if there are no explicit template arguments.
+ const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+ if (!hasExplicitTemplateArgs()) return 0;
+ return &getExplicitTemplateArgs();
}
static bool classof(const Stmt *T) {
@@ -1526,11 +1501,11 @@ class UnresolvedLookupExpr : public OverloadExpr {
UnresolvedLookupExpr(ASTContext &C, QualType T, bool Dependent,
CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier, SourceRange QRange,
- DeclarationName Name, SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
bool RequiresADL, bool Overloaded, bool HasTemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End)
: OverloadExpr(UnresolvedLookupExprClass, C, T, Dependent, Qualifier,
- QRange, Name, NameLoc, HasTemplateArgs, Begin, End),
+ QRange, NameInfo, HasTemplateArgs, Begin, End),
RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
{}
@@ -1545,16 +1520,15 @@ public:
CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- DeclarationName Name,
- SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
bool ADL, bool Overloaded,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
return new(C) UnresolvedLookupExpr(C,
Dependent ? C.DependentTy : C.OverloadTy,
Dependent, NamingClass,
- Qualifier, QualifierRange,
- Name, NameLoc, ADL, Overloaded, false,
+ Qualifier, QualifierRange, NameInfo,
+ ADL, Overloaded, false,
Begin, End);
}
@@ -1563,8 +1537,7 @@ public:
CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- DeclarationName Name,
- SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
bool ADL,
const TemplateArgumentListInfo &Args,
UnresolvedSetIterator Begin,
@@ -1603,6 +1576,14 @@ public:
return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
}
+ /// \brief Retrieves the optional explicit template arguments.
+ /// This points to the same data as getExplicitTemplateArgs(), but
+ /// returns null if there are no explicit template arguments.
+ const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+ if (!hasExplicitTemplateArgs()) return 0;
+ return &getExplicitTemplateArgs();
+ }
+
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
@@ -1626,7 +1607,7 @@ public:
}
virtual SourceRange getSourceRange() const {
- SourceRange Range(getNameLoc());
+ SourceRange Range(getNameInfo().getSourceRange());
if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
return Range;
@@ -1657,10 +1638,7 @@ public:
/// declaration can be found.
class DependentScopeDeclRefExpr : public Expr {
/// The name of the entity we will be referencing.
- DeclarationName Name;
-
- /// Location of the name of the declaration we're referencing.
- SourceLocation Loc;
+ DeclarationNameInfo NameInfo;
/// QualifierRange - The source range that covers the
/// nested-name-specifier.
@@ -1676,12 +1654,10 @@ class DependentScopeDeclRefExpr : public Expr {
DependentScopeDeclRefExpr(QualType T,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- DeclarationName Name,
- SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
bool HasExplicitTemplateArgs)
: Expr(DependentScopeDeclRefExprClass, T, true, true),
- Name(Name), Loc(NameLoc),
- QualifierRange(QualifierRange), Qualifier(Qualifier),
+ NameInfo(NameInfo), QualifierRange(QualifierRange), Qualifier(Qualifier),
HasExplicitTemplateArgs(HasExplicitTemplateArgs)
{}
@@ -1689,20 +1665,23 @@ public:
static DependentScopeDeclRefExpr *Create(ASTContext &C,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- DeclarationName Name,
- SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs = 0);
static DependentScopeDeclRefExpr *CreateEmpty(ASTContext &C,
unsigned NumTemplateArgs);
/// \brief Retrieve the name that this expression refers to.
- DeclarationName getDeclName() const { return Name; }
- void setDeclName(DeclarationName N) { Name = N; }
+ const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+ void setNameInfo(const DeclarationNameInfo &N) { NameInfo = N; }
+
+ /// \brief Retrieve the name that this expression refers to.
+ DeclarationName getDeclName() const { return NameInfo.getName(); }
+ void setDeclName(DeclarationName N) { NameInfo.setName(N); }
/// \brief Retrieve the location of the name within the expression.
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
+ SourceLocation getLocation() const { return NameInfo.getLoc(); }
+ void setLocation(SourceLocation L) { NameInfo.setLoc(L); }
/// \brief Retrieve the source range of the nested-name-specifier.
SourceRange getQualifierRange() const { return QualifierRange; }
@@ -1731,6 +1710,14 @@ public:
return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
}
+ /// \brief Retrieves the optional explicit template arguments.
+ /// This points to the same data as getExplicitTemplateArgs(), but
+ /// returns null if there are no explicit template arguments.
+ const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+ if (!hasExplicitTemplateArgs()) return 0;
+ return &getExplicitTemplateArgs();
+ }
+
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
@@ -1777,10 +1764,6 @@ class CXXExprWithTemporaries : public Expr {
CXXExprWithTemporaries(ASTContext &C, Expr *SubExpr, CXXTemporary **Temps,
unsigned NumTemps);
- ~CXXExprWithTemporaries();
-
-protected:
- virtual void DoDestroy(ASTContext &C);
public:
CXXExprWithTemporaries(EmptyShell Empty)
@@ -1991,10 +1974,7 @@ class CXXDependentScopeMemberExpr : public Expr {
/// \brief The member to which this member expression refers, which
/// can be name, overloaded operator, or destructor.
/// FIXME: could also be a template-id
- DeclarationName Member;
-
- /// \brief The location of the member name.
- SourceLocation MemberLoc;
+ DeclarationNameInfo MemberNameInfo;
CXXDependentScopeMemberExpr(ASTContext &C,
Expr *Base, QualType BaseType, bool IsArrow,
@@ -2002,8 +1982,7 @@ class CXXDependentScopeMemberExpr : public Expr {
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NamedDecl *FirstQualifierFoundInScope,
- DeclarationName Member,
- SourceLocation MemberLoc,
+ DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);
public:
@@ -2014,14 +1993,13 @@ public:
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NamedDecl *FirstQualifierFoundInScope,
- DeclarationName Member,
- SourceLocation MemberLoc)
+ DeclarationNameInfo MemberNameInfo)
: Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
Base(Base), BaseType(BaseType), IsArrow(IsArrow),
HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc),
Qualifier(Qualifier), QualifierRange(QualifierRange),
FirstQualifierFoundInScope(FirstQualifierFoundInScope),
- Member(Member), MemberLoc(MemberLoc) { }
+ MemberNameInfo(MemberNameInfo) { }
static CXXDependentScopeMemberExpr *
Create(ASTContext &C,
@@ -2030,8 +2008,7 @@ public:
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NamedDecl *FirstQualifierFoundInScope,
- DeclarationName Member,
- SourceLocation MemberLoc,
+ DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);
static CXXDependentScopeMemberExpr *
@@ -2092,13 +2069,20 @@ public:
/// \brief Retrieve the name of the member that this expression
/// refers to.
- DeclarationName getMember() const { return Member; }
- void setMember(DeclarationName N) { Member = N; }
+ 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 MemberLoc; }
- void setMemberLoc(SourceLocation L) { MemberLoc = L; }
+ 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>.
@@ -2108,57 +2092,59 @@ public:
/// \brief Retrieve the explicit template argument list that followed the
/// member template name, if any.
- ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
assert(HasExplicitTemplateArgs);
- return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
}
/// \brief Retrieve the explicit template argument list that followed the
/// member template name, if any.
- const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
return const_cast<CXXDependentScopeMemberExpr *>(this)
- ->getExplicitTemplateArgumentList();
+ ->getExplicitTemplateArgs();
+ }
+
+ /// \brief Retrieves the optional explicit template arguments.
+ /// This points to the same data as getExplicitTemplateArgs(), but
+ /// returns null if there are no explicit template arguments.
+ const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+ if (!hasExplicitTemplateArgs()) return 0;
+ return &getExplicitTemplateArgs();
}
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- assert(HasExplicitTemplateArgs);
- getExplicitTemplateArgumentList()->copyInto(List);
+ getExplicitTemplateArgs().copyInto(List);
}
/// \brief Initializes the template arguments using the given structure.
void initializeTemplateArgumentsFrom(const TemplateArgumentListInfo &List) {
- assert(HasExplicitTemplateArgs);
- getExplicitTemplateArgumentList()->initializeFrom(List);
+ getExplicitTemplateArgs().initializeFrom(List);
}
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
- assert(HasExplicitTemplateArgs);
- return getExplicitTemplateArgumentList()->LAngleLoc;
+ return getExplicitTemplateArgs().LAngleLoc;
}
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
- assert(HasExplicitTemplateArgs);
- return getExplicitTemplateArgumentList()->getTemplateArgs();
+ return getExplicitTemplateArgs().getTemplateArgs();
}
/// \brief Retrieve the number of template arguments provided as part of this
/// template-id.
unsigned getNumTemplateArgs() const {
- assert(HasExplicitTemplateArgs);
- return getExplicitTemplateArgumentList()->NumTemplateArgs;
+ return getExplicitTemplateArgs().NumTemplateArgs;
}
/// \brief Retrieve the location of the right angle bracket following the
/// template arguments ('>').
SourceLocation getRAngleLoc() const {
- assert(HasExplicitTemplateArgs);
- return getExplicitTemplateArgumentList()->RAngleLoc;
+ return getExplicitTemplateArgs().RAngleLoc;
}
virtual SourceRange getSourceRange() const {
@@ -2168,12 +2154,12 @@ public:
else if (getQualifier())
Range.setBegin(getQualifierRange().getBegin());
else
- Range.setBegin(MemberLoc);
+ Range.setBegin(MemberNameInfo.getBeginLoc());
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());
else
- Range.setEnd(MemberLoc);
+ Range.setEnd(MemberNameInfo.getEndLoc());
return Range;
}
@@ -2226,8 +2212,7 @@ class UnresolvedMemberExpr : public OverloadExpr {
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- DeclarationName Member,
- SourceLocation MemberLoc,
+ const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
@@ -2242,8 +2227,7 @@ public:
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- DeclarationName Member,
- SourceLocation MemberLoc,
+ const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
@@ -2287,6 +2271,11 @@ public:
/// \brief Retrieves the naming class of this lookup.
CXXRecordDecl *getNamingClass() const;
+ /// \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(); }
@@ -2311,6 +2300,14 @@ public:
return *reinterpret_cast<const ExplicitTemplateArgumentList *>(this + 1);
}
+ /// \brief Retrieves the optional explicit template arguments.
+ /// This points to the same data as getExplicitTemplateArgs(), but
+ /// returns null if there are no explicit template arguments.
+ const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+ if (!hasExplicitTemplateArgs()) return 0;
+ return &getExplicitTemplateArgs();
+ }
+
/// \brief Copies the template arguments into the given structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
getExplicitTemplateArgs().copyInto(List);
@@ -2341,18 +2338,14 @@ public:
}
virtual SourceRange getSourceRange() const {
- SourceRange Range;
+ SourceRange Range = getMemberNameInfo().getSourceRange();
if (!isImplicitAccess())
Range.setBegin(Base->getSourceRange().getBegin());
else if (getQualifier())
Range.setBegin(getQualifierRange().getBegin());
- else
- Range.setBegin(getMemberLoc());
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());
- else
- Range.setEnd(getMemberLoc());
return Range;
}
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index def9ced..a8ef005 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -14,31 +14,25 @@
#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
#define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Type.h"
-#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <vector>
+
+namespace llvm {
+template <class T> class SmallVectorImpl;
+}
+
namespace clang {
class ASTConsumer;
class Decl;
class DeclContext;
+class DeclContextLookupResult;
+class DeclarationName;
class ExternalSemaSource; // layering violation required for downcasting
+class NamedDecl;
+class Selector;
class Stmt;
-/// \brief The deserialized representation of a set of declarations
-/// with the same name that are visible in a given context.
-struct VisibleDeclaration {
- /// \brief The name of the declarations.
- DeclarationName Name;
-
- /// \brief The ID numbers of all of the declarations with this name.
- ///
- /// These declarations have not necessarily been de-serialized.
- llvm::SmallVector<unsigned, 4> Declarations;
-};
-
/// \brief Abstract interface for external sources of AST nodes.
///
/// External AST sources provide AST nodes constructed from some
@@ -58,6 +52,20 @@ public:
virtual ~ExternalASTSource();
+ /// \brief RAII class for safely pairing a StartedDeserializing call
+ /// with FinishedDeserializing.
+ class Deserializing {
+ ExternalASTSource *Source;
+ public:
+ explicit Deserializing(ExternalASTSource *source) : Source(source) {
+ assert(Source);
+ Source->StartedDeserializing();
+ }
+ ~Deserializing() {
+ Source->FinishedDeserializing();
+ }
+ };
+
/// \brief Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
///
@@ -89,10 +97,18 @@ public:
/// Generally the final step of this method is either to call
/// SetExternalVisibleDeclsForName or to recursively call lookup on
/// the DeclContext after calling SetExternalVisibleDecls.
- virtual DeclContext::lookup_result
+ virtual DeclContextLookupResult
FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) = 0;
+ /// \brief Deserialize all the visible declarations from external storage.
+ ///
+ /// Name lookup deserializes visible declarations lazily, thus a DeclContext
+ /// 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;
+
/// \brief Finds all declarations lexically contained within the given
/// DeclContext.
///
@@ -100,6 +116,19 @@ public:
virtual bool FindExternalLexicalDecls(const DeclContext *DC,
llvm::SmallVectorImpl<Decl*> &Result) = 0;
+ /// \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.
+ ///
+ /// The default implementation of this method is a no-op.
+ virtual void StartedDeserializing() { }
+
+ /// \brief Notify ExternalASTSource that we finished the deserialization of
+ /// a decl or type. Must be paired with StartedDeserializing.
+ ///
+ /// The default implementation of this method is a no-op.
+ virtual void FinishedDeserializing() { }
+
/// \brief Function that will be invoked when we begin parsing a new
/// translation unit involving this external AST source.
///
@@ -113,30 +142,18 @@ public:
virtual void PrintStats();
protected:
- /// \brief Initialize the context's lookup map with the given decls.
- /// It is assumed that none of the declarations are redeclarations of
- /// each other.
- static void SetExternalVisibleDecls(const DeclContext *DC,
- const llvm::SmallVectorImpl<VisibleDeclaration> &Decls);
-
- /// \brief Initialize the context's lookup map with the given decls.
- /// It is assumed that none of the declarations are redeclarations of
- /// each other.
- static void SetExternalVisibleDecls(const DeclContext *DC,
- const llvm::SmallVectorImpl<NamedDecl*> &Decls);
-
- static DeclContext::lookup_result
- SetExternalVisibleDeclsForName(const DeclContext *DC,
- const VisibleDeclaration &VD);
-
- static DeclContext::lookup_result
+ static DeclContextLookupResult
SetExternalVisibleDeclsForName(const DeclContext *DC,
DeclarationName Name,
llvm::SmallVectorImpl<NamedDecl*> &Decls);
- static DeclContext::lookup_result
+ static DeclContextLookupResult
SetNoExternalVisibleDeclsForName(const DeclContext *DC,
DeclarationName Name);
+
+ void MaterializeVisibleDeclsForName(const DeclContext *DC,
+ DeclarationName Name,
+ llvm::SmallVectorImpl<NamedDecl*> &Decls);
};
/// \brief A lazy pointer to an AST node (of base type T) that resides
@@ -145,7 +162,7 @@ protected:
/// The AST node is identified within the external AST source by a
/// 63-bit offset, and can be retrieved via an operation on the
/// external AST source itself.
-template<typename T, T* (ExternalASTSource::*Get)(uint64_t Offset)>
+template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
struct LazyOffsetPtr {
/// \brief Either a pointer to an AST node or the offset within the
/// external AST source where the AST node can be found.
@@ -203,9 +220,13 @@ public:
};
/// \brief A lazy pointer to a statement.
-typedef LazyOffsetPtr<Stmt, &ExternalASTSource::GetExternalDeclStmt>
+typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
LazyDeclStmtPtr;
+/// \brief A lazy pointer to a declaration.
+typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
+ LazyDeclPtr;
+
} // end namespace clang
#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
diff --git a/include/clang/AST/FullExpr.h b/include/clang/AST/FullExpr.h
index bb81bf0..6ceefed 100644
--- a/include/clang/AST/FullExpr.h
+++ b/include/clang/AST/FullExpr.h
@@ -47,7 +47,6 @@ class FullExpr {
public:
static FullExpr Create(ASTContext &Context, Expr *SubExpr,
CXXTemporary **Temps, unsigned NumTemps);
- void Destroy(ASTContext &Context);
Expr *getExpr() {
if (Expr *E = SubExpr.dyn_cast<Expr *>())
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
index 00a1e1b..6ba6e89 100644
--- a/include/clang/AST/Makefile
+++ b/include/clang/AST/Makefile
@@ -1,6 +1,6 @@
CLANG_LEVEL := ../../..
TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = Attrs.inc StmtNodes.inc DeclNodes.inc
+BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc
TABLEGEN_INC_FILES_COMMON = 1
@@ -12,6 +12,12 @@ $(ObjDir)/Attrs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
$(Verb) $(TableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../../ $<
+$(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang attribute implementations with tblgen"
+ $(Verb) $(TableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../../ $<
+
$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(TBLGEN) \
$(ObjDir)/.dir
$(Echo) "Building Clang statement node tables with tblgen"
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index 1594b09..3b25f3b 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -181,8 +181,6 @@ public:
ID.AddPointer(Specifier);
}
- void Destroy(ASTContext &Context);
-
/// \brief Dump the nested name specifier to standard output to aid
/// in debugging.
void dump(const LangOptions &LO);
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
new file mode 100644
index 0000000..8045311
--- /dev/null
+++ b/include/clang/AST/OperationKinds.h
@@ -0,0 +1,158 @@
+//===- OperationKinds.h - Operation enums -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates the different kinds of operations that can be
+// performed by various expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_OPERATION_KINDS_H
+#define LLVM_CLANG_AST_OPERATION_KINDS_H
+
+namespace clang {
+
+/// CastKind - the kind of cast this represents.
+enum CastKind {
+ /// CK_Unknown - Unknown cast kind.
+ /// FIXME: The goal is to get rid of this and make all casts have a
+ /// kind so that the AST client doesn't have to try to figure out what's
+ /// going on.
+ CK_Unknown,
+
+ /// CK_BitCast - Used for reinterpret_cast.
+ CK_BitCast,
+
+ /// CK_LValueBitCast - Used for reinterpret_cast of expressions to
+ /// a reference type.
+ CK_LValueBitCast,
+
+ /// CK_NoOp - Used for const_cast.
+ CK_NoOp,
+
+ /// CK_BaseToDerived - Base to derived class casts.
+ CK_BaseToDerived,
+
+ /// CK_DerivedToBase - Derived to base class casts.
+ CK_DerivedToBase,
+
+ /// CK_UncheckedDerivedToBase - Derived to base class casts that
+ /// assume that the derived pointer is not null.
+ CK_UncheckedDerivedToBase,
+
+ /// CK_Dynamic - Dynamic cast.
+ CK_Dynamic,
+
+ /// CK_ToUnion - Cast to union (GCC extension).
+ CK_ToUnion,
+
+ /// CK_ArrayToPointerDecay - Array to pointer decay.
+ CK_ArrayToPointerDecay,
+
+ // CK_FunctionToPointerDecay - Function to pointer decay.
+ CK_FunctionToPointerDecay,
+
+ /// CK_NullToMemberPointer - Null pointer to member pointer.
+ CK_NullToMemberPointer,
+
+ /// CK_BaseToDerivedMemberPointer - Member pointer in base class to
+ /// member pointer in derived class.
+ CK_BaseToDerivedMemberPointer,
+
+ /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to
+ /// member pointer in base class.
+ CK_DerivedToBaseMemberPointer,
+
+ /// CK_UserDefinedConversion - Conversion using a user defined type
+ /// conversion function.
+ CK_UserDefinedConversion,
+
+ /// CK_ConstructorConversion - Conversion by constructor
+ CK_ConstructorConversion,
+
+ /// CK_IntegralToPointer - Integral to pointer
+ CK_IntegralToPointer,
+
+ /// CK_PointerToIntegral - Pointer to integral
+ CK_PointerToIntegral,
+
+ /// CK_ToVoid - Cast to void.
+ CK_ToVoid,
+
+ /// CK_VectorSplat - Casting from an integer/floating type to an extended
+ /// vector type with the same element type as the src type. Splats the
+ /// src expression into the destination expression.
+ CK_VectorSplat,
+
+ /// CK_IntegralCast - Casting between integral types of different size.
+ CK_IntegralCast,
+
+ /// CK_IntegralToFloating - Integral to floating point.
+ CK_IntegralToFloating,
+
+ /// CK_FloatingToIntegral - Floating point to integral.
+ CK_FloatingToIntegral,
+
+ /// CK_FloatingCast - Casting between floating types of different size.
+ CK_FloatingCast,
+
+ /// CK_MemberPointerToBoolean - Member pointer to boolean
+ CK_MemberPointerToBoolean,
+
+ /// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c
+ /// pointer
+ CK_AnyPointerToObjCPointerCast,
+
+ /// CK_AnyPointerToBlockPointerCast - Casting any pointer to block
+ /// pointer
+ CK_AnyPointerToBlockPointerCast,
+
+ /// \brief Converting between two Objective-C object types, which
+ /// can occur when performing reference binding to an Objective-C
+ /// object.
+ CK_ObjCObjectLValueCast
+};
+
+
+enum BinaryOperatorKind {
+ // Operators listed in order of precedence.
+ // Note that additions to this should also update the StmtVisitor class.
+ BO_PtrMemD, BO_PtrMemI, // [C++ 5.5] Pointer-to-member operators.
+ BO_Mul, BO_Div, BO_Rem, // [C99 6.5.5] Multiplicative operators.
+ BO_Add, BO_Sub, // [C99 6.5.6] Additive operators.
+ BO_Shl, BO_Shr, // [C99 6.5.7] Bitwise shift operators.
+ BO_LT, BO_GT, BO_LE, BO_GE, // [C99 6.5.8] Relational operators.
+ BO_EQ, BO_NE, // [C99 6.5.9] Equality operators.
+ BO_And, // [C99 6.5.10] Bitwise AND operator.
+ BO_Xor, // [C99 6.5.11] Bitwise XOR operator.
+ BO_Or, // [C99 6.5.12] Bitwise OR operator.
+ BO_LAnd, // [C99 6.5.13] Logical AND operator.
+ BO_LOr, // [C99 6.5.14] Logical OR operator.
+ BO_Assign, BO_MulAssign, // [C99 6.5.16] Assignment operators.
+ BO_DivAssign, BO_RemAssign,
+ BO_AddAssign, BO_SubAssign,
+ BO_ShlAssign, BO_ShrAssign,
+ BO_AndAssign, BO_XorAssign,
+ BO_OrAssign,
+ BO_Comma // [C99 6.5.17] Comma operator.
+};
+
+enum UnaryOperatorKind {
+ // Note that additions to this should also update the StmtVisitor class.
+ UO_PostInc, UO_PostDec, // [C99 6.5.2.4] Postfix increment and decrement
+ UO_PreInc, UO_PreDec, // [C99 6.5.3.1] Prefix increment and decrement
+ UO_AddrOf, UO_Deref, // [C99 6.5.3.2] Address and indirection
+ UO_Plus, UO_Minus, // [C99 6.5.3.3] Unary arithmetic
+ UO_Not, UO_LNot, // [C99 6.5.3.3] Unary arithmetic
+ UO_Real, UO_Imag, // "__real expr"/"__imag expr" Extension.
+ UO_Extension // __extension__ marker.
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 0853ddd..232e47b 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -42,7 +42,7 @@
OPERATOR(Plus) OPERATOR(Minus) \
OPERATOR(Not) OPERATOR(LNot) \
OPERATOR(Real) OPERATOR(Imag) \
- OPERATOR(Extension) OPERATOR(OffsetOf)
+ OPERATOR(Extension)
// All binary operators (excluding compound assign operators).
#define BINOP_LIST() \
@@ -123,12 +123,27 @@ namespace clang {
/// users may override Traverse* and WalkUpFrom* to implement custom
/// traversal strategies. Returning false from one of these overridden
/// functions will abort the entire traversal.
+///
+/// By default, this visitor tries to visit every part of the explicit
+/// source code exactly once. The default policy towards templates
+/// is to descend into the 'pattern' class or function body, not any
+/// explicit or implicit instantiations. Explicit specializations
+/// are still visited, and the patterns of partial specializations
+/// are visited separately. This behavior can be changed by
+/// overriding shouldVisitTemplateInstantiations() in the derived class
+/// to return true, in which case all known implicit and explicit
+/// instantiations will be visited at the same time as the pattern
+/// from which they were produced.
template<typename Derived>
class RecursiveASTVisitor {
public:
/// \brief Return a reference to the derived class.
Derived &getDerived() { return *static_cast<Derived*>(this); }
+ /// \brief Return whether this visitor should recurse into
+ /// template instantiations.
+ bool shouldVisitTemplateInstantiations() const { return false; }
+
/// \brief Recursively visit a statement or expression, by
/// dispatching to Traverse*() based on the argument's dynamic type.
///
@@ -351,8 +366,11 @@ public:
private:
// These are helper methods used by more than one Traverse* method.
bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
- bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
+ bool TraverseClassInstantiations(ClassTemplateDecl* D, Decl *Pattern);
+ bool TraverseFunctionInstantiations(FunctionTemplateDecl* D) ;
+ bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
unsigned Count);
+ bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
bool TraverseRecordHelper(RecordDecl *D);
bool TraverseCXXRecordHelper(CXXRecordDecl *D);
bool TraverseDeclaratorHelper(DeclaratorDecl *D);
@@ -375,14 +393,14 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
#define OPERATOR(NAME) \
- case BinaryOperator::NAME: DISPATCH(Bin##PtrMemD, BinaryOperator, S);
+ case BO_##NAME: DISPATCH(Bin##PtrMemD, BinaryOperator, S);
BINOP_LIST()
#undef OPERATOR
#undef BINOP_LIST
#define OPERATOR(NAME) \
- case BinaryOperator::NAME##Assign: \
+ case BO_##NAME##Assign: \
DISPATCH(Bin##NAME##Assign, CompoundAssignOperator, S);
CAO_LIST()
@@ -392,7 +410,7 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
switch (UnOp->getOpcode()) {
#define OPERATOR(NAME) \
- case UnaryOperator::NAME: DISPATCH(Unary##NAME, UnaryOperator, S);
+ case UO_##NAME: DISPATCH(Unary##NAME, UnaryOperator, S);
UNARYOP_LIST()
#undef OPERATOR
@@ -540,8 +558,11 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
return true;
case TemplateArgument::Type: {
- TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo();
- return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
+ // FIXME: how can TSI ever be NULL?
+ if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
+ return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
+ else
+ return true;
}
case TemplateArgument::Template:
@@ -796,23 +817,31 @@ DEF_TRAVERSE_TYPELOC(MemberPointerType, {
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
})
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
+ // This isn't available for ArrayType, but is for the ArrayTypeLoc.
+ TRY_TO(TraverseStmt(TL.getSizeExpr()));
+ return true;
+}
+
DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
})
DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
})
DEF_TRAVERSE_TYPELOC(VariableArrayType, {
TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ return TraverseArrayTypeLocHelper(TL);
})
DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- if (TL.getTypePtr()->getSizeExpr())
- TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ return TraverseArrayTypeLocHelper(TL);
})
// FIXME: order? why not size expr first?
@@ -1083,19 +1112,124 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
return true;
}
+// A helper method for traversing the implicit instantiations of a
+// class.
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseClassInstantiations(
+ ClassTemplateDecl* D, Decl *Pattern) {
+ assert(isa<ClassTemplateDecl>(Pattern) ||
+ isa<ClassTemplatePartialSpecializationDecl>(Pattern));
+
+ ClassTemplateDecl::spec_iterator end = D->spec_end();
+ for (ClassTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) {
+ ClassTemplateSpecializationDecl* SD = *it;
+
+ switch (SD->getSpecializationKind()) {
+ // Visit the implicit instantiations with the requested pattern.
+ case TSK_ImplicitInstantiation: {
+ llvm::PointerUnion<ClassTemplateDecl *,
+ ClassTemplatePartialSpecializationDecl *> U
+ = SD->getInstantiatedFrom();
+
+ bool ShouldVisit;
+ if (U.is<ClassTemplateDecl*>())
+ ShouldVisit = (U.get<ClassTemplateDecl*>() == Pattern);
+ else
+ ShouldVisit
+ = (U.get<ClassTemplatePartialSpecializationDecl*>() == Pattern);
+
+ if (ShouldVisit)
+ TRY_TO(TraverseClassTemplateSpecializationDecl(SD));
+ break;
+ }
+
+ // We don't need to do anything on an explicit instantiation
+ // or explicit specialization because there will be an explicit
+ // node for it elsewhere.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ case TSK_ExplicitSpecialization:
+ break;
+
+ // We don't need to do anything for an uninstantiated
+ // specialization.
+ case TSK_Undeclared:
+ break;
+ }
+ }
+
+ return true;
+}
+
DEF_TRAVERSE_DECL(ClassTemplateDecl, {
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ CXXRecordDecl* TempDecl = D->getTemplatedDecl();
+ TRY_TO(TraverseDecl(TempDecl));
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- // We should not traverse the specializations/partial
- // specializations. Those will show up in other contexts.
- // getInstantiatedFromMemberTemplate() is just a link from a
- // template instantiation back to the template from which it was
- // instantiated, and thus should not be traversed either.
+
+ // By default, we do not traverse the instantiations of
+ // class templates since they do not apprear in the user code. The
+ // following code optionally traverses them.
+ if (getDerived().shouldVisitTemplateInstantiations()) {
+ // If this is the definition of the primary template, visit
+ // instantiations which were formed from this pattern.
+ if (D->isThisDeclarationADefinition())
+ TRY_TO(TraverseClassInstantiations(D, D));
+ }
+
+ // Note that getInstantiatedFromMemberTemplate() is just a link
+ // from a template instantiation back to the template from which
+ // it was instantiated, and thus should not be traversed.
})
+// A helper method for traversing the instantiations of a
+// function while skipping its specializations.
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations(
+ FunctionTemplateDecl* D) {
+ FunctionTemplateDecl::spec_iterator end = D->spec_end();
+ for (FunctionTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) {
+ FunctionDecl* FD = *it;
+ switch (FD->getTemplateSpecializationKind()) {
+ case TSK_ImplicitInstantiation:
+ // We don't know what kind of FunctionDecl this is.
+ TRY_TO(TraverseDecl(FD));
+ break;
+
+ // No need to visit explicit instantiations, we'll find the node
+ // eventually.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ break;
+
+ case TSK_Undeclared: // Declaration of the template definition.
+ case TSK_ExplicitSpecialization:
+ break;
+ default:
+ assert(false && "Unknown specialization kind.");
+ }
+ }
+
+ return true;
+}
+
DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
TRY_TO(TraverseDecl(D->getTemplatedDecl()));
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+ // By default, we do not traverse the instantiations of
+ // function templates since they do not apprear in the user code. The
+ // following code optionally traverses them.
+ if (getDerived().shouldVisitTemplateInstantiations()) {
+ // Explicit function specializations will be traversed from the
+ // context of their declaration. There is therefore no need to
+ // traverse them for here.
+ //
+ // In addition, we only traverse the function instantiations when
+ // the function template is a function template definition.
+ if (D->isThisDeclarationADefinition()) {
+ TRY_TO(TraverseFunctionInstantiations(D));
+ }
+ }
})
DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
@@ -1110,10 +1244,10 @@ DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
// D is the "T" in something like "template<typename T> class vector;"
- if (D->hasDefaultArgument())
- TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
if (D->getTypeForDecl())
TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+ if (D->hasDefaultArgument())
+ TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
})
DEF_TRAVERSE_DECL(TypedefDecl, {
@@ -1166,7 +1300,7 @@ bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(
for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
E = D->bases_end();
I != E; ++I) {
- TRY_TO(TraverseType(I->getType()));
+ TRY_TO(TraverseTypeLoc(I->getTypeSourceInfo()->getTypeLoc()));
}
// We don't traverse the friends or the conversions, as they are
// already in decls_begin()/decls_end().
@@ -1191,10 +1325,16 @@ DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, {
// ("template set<int>;"), we do need a callback, since this
// is the only callback that's made for this instantiation.
// We use getTypeAsWritten() to distinguish.
- // FIXME: see how we want to handle template specializations.
if (TypeSourceInfo *TSI = D->getTypeAsWritten())
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
- return true;
+
+ if (!getDerived().shouldVisitTemplateInstantiations() &&
+ D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+ // Returning from here skips traversing the
+ // declaration context of the ClassTemplateSpecializationDecl
+ // (embedded in the DEF_TRAVERSE_DECL() macro)
+ // which contains the instantiated members of the class.
+ return true;
})
template <typename Derived>
@@ -1222,6 +1362,12 @@ DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, {
// though that's our parent class -- we already visit all the
// template args here.
TRY_TO(TraverseCXXRecordHelper(D));
+
+ // If we're visiting instantiations, visit the instantiations of
+ // this template now.
+ if (getDerived().shouldVisitTemplateInstantiations() &&
+ D->isThisDeclarationADefinition())
+ TRY_TO(TraverseClassInstantiations(D->getSpecializedTemplate(), D));
})
DEF_TRAVERSE_DECL(EnumConstantDecl, {
@@ -1304,7 +1450,45 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
}
TRY_TO(TraverseType(D->getResultType()));
- TRY_TO(TraverseDeclContextHelper(D)); // Parameters.
+
+ // If we're an explicit template specialization, iterate over the
+ // template args that were explicitly specified.
+ if (const FunctionTemplateSpecializationInfo *FTSI =
+ D->getTemplateSpecializationInfo()) {
+ if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
+ FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
+ // A specialization might not have explicit template arguments if it has
+ // a templated return type and concrete arguments.
+ if (const TemplateArgumentListInfo *TALI =
+ FTSI->TemplateArgumentsAsWritten) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getArgumentArray(),
+ TALI->size()));
+ }
+ }
+ }
+
+ for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+
+ if (FunctionProtoType *FuncProto = dyn_cast<FunctionProtoType>(FuncType)) {
+ if (D->isThisDeclarationADefinition()) {
+ // This would be visited if we called TraverseType(D->getType())
+ // above, but we don't (at least, not in the
+ // declaration-is-a-definition case), in order to avoid duplicate
+ // visiting for parameters. (We need to check parameters here,
+ // rather than letting D->getType() do it, so we visit default
+ // parameter values). So we need to re-do some of the work the
+ // type would do.
+ for (FunctionProtoType::exception_iterator
+ E = FuncProto->exception_begin(),
+ EEnd = FuncProto->exception_end();
+ E != EEnd; ++E) {
+ TRY_TO(TraverseType(*E));
+ }
+ }
+ }
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
// Constructor initializers.
@@ -1356,9 +1540,6 @@ DEF_TRAVERSE_DECL(CXXDestructorDecl, {
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
TRY_TO(TraverseDeclaratorHelper(D));
- // FIXME: This often double-counts -- for instance, for all local
- // vars, though not for global vars -- because the initializer is
- // also captured when the var-decl is in a DeclStmt.
TRY_TO(TraverseStmt(D->getInit()));
return true;
}
@@ -1373,11 +1554,13 @@ DEF_TRAVERSE_DECL(ImplicitParamDecl, {
DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
// A non-type template parameter, e.g. "S" in template<int S> class Foo ...
- TRY_TO(TraverseStmt(D->getDefaultArgument()));
TRY_TO(TraverseVarHelper(D));
+ TRY_TO(TraverseStmt(D->getDefaultArgument()));
})
DEF_TRAVERSE_DECL(ParmVarDecl, {
+ TRY_TO(TraverseVarHelper(D));
+
if (D->hasDefaultArg() &&
D->hasUninstantiatedDefaultArg() &&
!D->hasUnparsedDefaultArg())
@@ -1387,8 +1570,6 @@ DEF_TRAVERSE_DECL(ParmVarDecl, {
!D->hasUninstantiatedDefaultArg() &&
!D->hasUnparsedDefaultArg())
TRY_TO(TraverseStmt(D->getDefaultArg()));
-
- TRY_TO(TraverseVarHelper(D));
})
#undef DEF_TRAVERSE_DECL
@@ -1431,35 +1612,36 @@ DEF_TRAVERSE_STMT(AsmStmt, {
})
DEF_TRAVERSE_STMT(CXXCatchStmt, {
- // We don't traverse S->getCaughtType(), as we are already
- // traversing the exception object, which has this type.
+ TRY_TO(TraverseDecl(S->getExceptionDecl()));
// child_begin()/end() iterates over the handler block.
})
-DEF_TRAVERSE_STMT(ForStmt, {
- TRY_TO(TraverseDecl(S->getConditionVariable()));
- // child_begin()/end() iterates over init, cond, inc, and body stmts.
- })
-
-DEF_TRAVERSE_STMT(IfStmt, {
- TRY_TO(TraverseDecl(S->getConditionVariable()));
- // child_begin()/end() iterates over cond, then, and else stmts.
+DEF_TRAVERSE_STMT(DeclStmt, {
+ for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ // Suppress the default iteration over child_begin/end by
+ // returning. Here's why: A DeclStmt looks like 'type var [=
+ // initializer]'. The decls above already traverse over the
+ // initializers, so we don't have to do it again (which
+ // child_begin/end would do).
+ return true;
})
-DEF_TRAVERSE_STMT(WhileStmt, {
- TRY_TO(TraverseDecl(S->getConditionVariable()));
- // child_begin()/end() iterates over cond, then, and else stmts.
- })
// These non-expr stmts (most of them), do not need any action except
// iterating over the children.
DEF_TRAVERSE_STMT(BreakStmt, { })
+DEF_TRAVERSE_STMT(CXXTryStmt, { })
+DEF_TRAVERSE_STMT(CaseStmt, { })
DEF_TRAVERSE_STMT(CompoundStmt, { })
DEF_TRAVERSE_STMT(ContinueStmt, { })
-DEF_TRAVERSE_STMT(CXXTryStmt, { })
-DEF_TRAVERSE_STMT(DeclStmt, { })
+DEF_TRAVERSE_STMT(DefaultStmt, { })
DEF_TRAVERSE_STMT(DoStmt, { })
+DEF_TRAVERSE_STMT(ForStmt, { })
DEF_TRAVERSE_STMT(GotoStmt, { })
+DEF_TRAVERSE_STMT(IfStmt, { })
DEF_TRAVERSE_STMT(IndirectGotoStmt, { })
DEF_TRAVERSE_STMT(LabelStmt, { })
DEF_TRAVERSE_STMT(NullStmt, { })
@@ -1470,10 +1652,10 @@ DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
DEF_TRAVERSE_STMT(ReturnStmt, { })
-DEF_TRAVERSE_STMT(SwitchStmt, { })
DEF_TRAVERSE_STMT(SwitchCase, { })
-DEF_TRAVERSE_STMT(CaseStmt, { })
-DEF_TRAVERSE_STMT(DefaultStmt, { })
+DEF_TRAVERSE_STMT(SwitchStmt, { })
+DEF_TRAVERSE_STMT(WhileStmt, { })
+
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
if (S->hasExplicitTemplateArgs()) {
@@ -1565,6 +1747,37 @@ DEF_TRAVERSE_STMT(CXXNewExpr, {
TRY_TO(TraverseType(S->getAllocatedType()));
})
+DEF_TRAVERSE_STMT(OffsetOfExpr, {
+ // The child-iterator will pick up the expression representing
+ // the field.
+ // FIMXE: for code like offsetof(Foo, a.b.c), should we get
+ // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_STMT(SizeOfAlignOfExpr, {
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isArgumentType())
+ TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_STMT(CXXTypeidExpr, {
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isTypeOperand())
+ TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_STMT(TypesCompatibleExpr, {
+ TRY_TO(TraverseTypeLoc(S->getArgTInfo1()->getTypeLoc()));
+ TRY_TO(TraverseTypeLoc(S->getArgTInfo2()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, {
+ TRY_TO(TraverseType(S->getQueriedType()));
+ })
+
// These exprs (most of them), do not need any action except iterating
// over the children.
DEF_TRAVERSE_STMT(AddrLabelExpr, { })
@@ -1573,7 +1786,6 @@ DEF_TRAVERSE_STMT(BlockDeclRefExpr, { })
DEF_TRAVERSE_STMT(BlockExpr, { })
DEF_TRAVERSE_STMT(ChooseExpr, { })
DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXBindReferenceExpr, { })
DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
@@ -1583,7 +1795,6 @@ DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { })
DEF_TRAVERSE_STMT(CXXThisExpr, { })
DEF_TRAVERSE_STMT(CXXThrowExpr, { })
-DEF_TRAVERSE_STMT(CXXTypeidExpr, { })
DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { })
DEF_TRAVERSE_STMT(DesignatedInitExpr, { })
DEF_TRAVERSE_STMT(ExtVectorElementExpr, { })
@@ -1598,18 +1809,17 @@ DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
DEF_TRAVERSE_STMT(ObjCSuperExpr, { })
-DEF_TRAVERSE_STMT(OffsetOfExpr, { })
DEF_TRAVERSE_STMT(ParenExpr, { })
DEF_TRAVERSE_STMT(ParenListExpr, { })
DEF_TRAVERSE_STMT(PredefinedExpr, { })
DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
-DEF_TRAVERSE_STMT(SizeOfAlignOfExpr, { })
DEF_TRAVERSE_STMT(StmtExpr, { })
-DEF_TRAVERSE_STMT(TypesCompatibleExpr, { })
-DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, { })
DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { })
DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { })
-DEF_TRAVERSE_STMT(VAArgExpr, { })
+DEF_TRAVERSE_STMT(VAArgExpr, {
+ // The child-iterator will pick up the expression argument.
+ TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
+ })
DEF_TRAVERSE_STMT(CXXConstructExpr, { })
DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 55e1f84..ba77829 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -177,6 +177,9 @@ public:
static_cast<const decl_type*>(this)));
}
redecl_iterator redecls_end() const { return redecl_iterator(); }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
}
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index a0c95b1..62a6b64 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -151,22 +151,11 @@ public:
struct EmptyShell { };
protected:
- /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
- /// recursively release child AST nodes.
- void DestroyChildren(ASTContext& Ctx);
-
/// \brief Construct an empty statement.
explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC), RefCount(1) {
if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
}
- /// \brief Virtual method that performs the actual destruction of
- /// this statement.
- ///
- /// Subclasses should override this method (not Destroy()) to
- /// provide class-specific destruction.
- virtual void DoDestroy(ASTContext &Ctx);
-
public:
Stmt(StmtClass SC) : sClass(SC), RefCount(1) {
if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
@@ -181,13 +170,6 @@ public:
}
#endif
- /// \brief Destroy the current statement and its children.
- void Destroy(ASTContext &Ctx) {
- assert(RefCount >= 1);
- if (--RefCount == 0)
- DoDestroy(Ctx);
- }
-
/// \brief Increases the reference count for this statement.
///
/// Invoke the Retain() operation when this statement or expression
@@ -221,6 +203,7 @@ public:
/// This is useful in a debugger.
void dump() const;
void dump(SourceManager &SM) const;
+ void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
void dumpAll() const;
@@ -295,9 +278,6 @@ class DeclStmt : public Stmt {
DeclGroupRef DG;
SourceLocation StartLoc, EndLoc;
-protected:
- virtual void DoDestroy(ASTContext &Ctx);
-
public:
DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
@@ -671,9 +651,6 @@ public:
// over the initialization expression referenced by the condition variable.
virtual child_iterator child_begin();
virtual child_iterator child_end();
-
-protected:
- virtual void DoDestroy(ASTContext &Ctx);
};
/// SwitchStmt - This represents a 'switch' stmt.
@@ -685,9 +662,6 @@ class SwitchStmt : public Stmt {
SwitchCase *FirstCase;
SourceLocation SwitchLoc;
-protected:
- virtual void DoDestroy(ASTContext &Ctx);
-
public:
SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond);
@@ -794,9 +768,6 @@ public:
// Iterators
virtual child_iterator child_begin();
virtual child_iterator child_end();
-
-protected:
- virtual void DoDestroy(ASTContext &Ctx);
};
/// DoStmt - This represents a 'do/while' stmt.
@@ -910,9 +881,6 @@ public:
// Iterators
virtual child_iterator child_begin();
virtual child_iterator child_end();
-
-protected:
- virtual void DoDestroy(ASTContext &Ctx);
};
/// GotoStmt - This represents a direct goto.
@@ -1113,9 +1081,6 @@ class AsmStmt : public Stmt {
StringLiteral **Constraints;
Stmt **Exprs;
StringLiteral **Clobbers;
-
-protected:
- virtual void DoDestroy(ASTContext &Ctx);
public:
AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 4e87c27..0508f35 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -29,14 +29,14 @@ class CXXCatchStmt : public Stmt {
/// The handler block.
Stmt *HandlerBlock;
-protected:
- virtual void DoDestroy(ASTContext& Ctx);
-
public:
CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
: Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
HandlerBlock(handlerBlock) {}
+ CXXCatchStmt(EmptyShell Empty)
+ : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {}
+
virtual SourceRange getSourceRange() const {
return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
}
@@ -53,6 +53,8 @@ public:
virtual child_iterator child_begin();
virtual child_iterator child_end();
+
+ friend class ASTStmtReader;
};
/// CXXTryStmt - A C++ try block, including all handlers.
@@ -64,38 +66,46 @@ class CXXTryStmt : public Stmt {
CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
unsigned numHandlers);
+ CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
+ : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
+
+ Stmt const * const *getStmts() const {
+ return reinterpret_cast<Stmt const * const*>(this + 1);
+ }
+ Stmt **getStmts() {
+ return reinterpret_cast<Stmt **>(this + 1);
+ }
+
public:
static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
Stmt *tryBlock, Stmt **handlers,
unsigned numHandlers);
+ static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty,
+ unsigned numHandlers);
+
virtual SourceRange getSourceRange() const {
return SourceRange(getTryLoc(), getEndLoc());
}
SourceLocation getTryLoc() const { return TryLoc; }
SourceLocation getEndLoc() const {
- Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
- return Stmts[NumHandlers]->getLocEnd();
+ return getStmts()[NumHandlers]->getLocEnd();
}
CompoundStmt *getTryBlock() {
- Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
- return llvm::cast<CompoundStmt>(Stmts[0]);
+ return llvm::cast<CompoundStmt>(getStmts()[0]);
}
const CompoundStmt *getTryBlock() const {
- Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
- return llvm::cast<CompoundStmt>(Stmts[0]);
+ return llvm::cast<CompoundStmt>(getStmts()[0]);
}
unsigned getNumHandlers() const { return NumHandlers; }
CXXCatchStmt *getHandler(unsigned i) {
- Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
- return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
+ return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]);
}
const CXXCatchStmt *getHandler(unsigned i) const {
- Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
- return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
+ return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]);
}
static bool classof(const Stmt *T) {
@@ -105,6 +115,8 @@ public:
virtual child_iterator child_begin();
virtual child_iterator child_end();
+
+ friend class ASTStmtReader;
};
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
index 8078451..b8c141d 100644
--- a/include/clang/AST/StmtVisitor.h
+++ b/include/clang/AST/StmtVisitor.h
@@ -37,68 +37,57 @@ public:
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
default: assert(0 && "Unknown binary operator!");
- case BinaryOperator::PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator);
- case BinaryOperator::PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator);
- case BinaryOperator::Mul: DISPATCH(BinMul, BinaryOperator);
- case BinaryOperator::Div: DISPATCH(BinDiv, BinaryOperator);
- case BinaryOperator::Rem: DISPATCH(BinRem, BinaryOperator);
- case BinaryOperator::Add: DISPATCH(BinAdd, BinaryOperator);
- case BinaryOperator::Sub: DISPATCH(BinSub, BinaryOperator);
- case BinaryOperator::Shl: DISPATCH(BinShl, BinaryOperator);
- case BinaryOperator::Shr: DISPATCH(BinShr, BinaryOperator);
-
- case BinaryOperator::LT: DISPATCH(BinLT, BinaryOperator);
- case BinaryOperator::GT: DISPATCH(BinGT, BinaryOperator);
- case BinaryOperator::LE: DISPATCH(BinLE, BinaryOperator);
- case BinaryOperator::GE: DISPATCH(BinGE, BinaryOperator);
- case BinaryOperator::EQ: DISPATCH(BinEQ, BinaryOperator);
- case BinaryOperator::NE: DISPATCH(BinNE, BinaryOperator);
-
- case BinaryOperator::And: DISPATCH(BinAnd, BinaryOperator);
- case BinaryOperator::Xor: DISPATCH(BinXor, BinaryOperator);
- case BinaryOperator::Or : DISPATCH(BinOr, BinaryOperator);
- case BinaryOperator::LAnd: DISPATCH(BinLAnd, BinaryOperator);
- case BinaryOperator::LOr : DISPATCH(BinLOr, BinaryOperator);
- case BinaryOperator::Assign: DISPATCH(BinAssign, BinaryOperator);
- case BinaryOperator::MulAssign:
- DISPATCH(BinMulAssign, CompoundAssignOperator);
- case BinaryOperator::DivAssign:
- DISPATCH(BinDivAssign, CompoundAssignOperator);
- case BinaryOperator::RemAssign:
- DISPATCH(BinRemAssign, CompoundAssignOperator);
- case BinaryOperator::AddAssign:
- DISPATCH(BinAddAssign, CompoundAssignOperator);
- case BinaryOperator::SubAssign:
- DISPATCH(BinSubAssign, CompoundAssignOperator);
- case BinaryOperator::ShlAssign:
- DISPATCH(BinShlAssign, CompoundAssignOperator);
- case BinaryOperator::ShrAssign:
- DISPATCH(BinShrAssign, CompoundAssignOperator);
- case BinaryOperator::AndAssign:
- DISPATCH(BinAndAssign, CompoundAssignOperator);
- case BinaryOperator::OrAssign:
- DISPATCH(BinOrAssign, CompoundAssignOperator);
- case BinaryOperator::XorAssign:
- DISPATCH(BinXorAssign, CompoundAssignOperator);
- case BinaryOperator::Comma: DISPATCH(BinComma, BinaryOperator);
+ case BO_PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator);
+ case BO_PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator);
+ case BO_Mul: DISPATCH(BinMul, BinaryOperator);
+ case BO_Div: DISPATCH(BinDiv, BinaryOperator);
+ case BO_Rem: DISPATCH(BinRem, BinaryOperator);
+ case BO_Add: DISPATCH(BinAdd, BinaryOperator);
+ case BO_Sub: DISPATCH(BinSub, BinaryOperator);
+ case BO_Shl: DISPATCH(BinShl, BinaryOperator);
+ case BO_Shr: DISPATCH(BinShr, BinaryOperator);
+
+ case BO_LT: DISPATCH(BinLT, BinaryOperator);
+ case BO_GT: DISPATCH(BinGT, BinaryOperator);
+ case BO_LE: DISPATCH(BinLE, BinaryOperator);
+ case BO_GE: DISPATCH(BinGE, BinaryOperator);
+ case BO_EQ: DISPATCH(BinEQ, BinaryOperator);
+ case BO_NE: DISPATCH(BinNE, BinaryOperator);
+
+ case BO_And: DISPATCH(BinAnd, BinaryOperator);
+ case BO_Xor: DISPATCH(BinXor, BinaryOperator);
+ case BO_Or : DISPATCH(BinOr, BinaryOperator);
+ case BO_LAnd: DISPATCH(BinLAnd, BinaryOperator);
+ case BO_LOr : DISPATCH(BinLOr, BinaryOperator);
+ case BO_Assign: DISPATCH(BinAssign, BinaryOperator);
+ case BO_MulAssign: DISPATCH(BinMulAssign, CompoundAssignOperator);
+ case BO_DivAssign: DISPATCH(BinDivAssign, CompoundAssignOperator);
+ case BO_RemAssign: DISPATCH(BinRemAssign, CompoundAssignOperator);
+ case BO_AddAssign: DISPATCH(BinAddAssign, CompoundAssignOperator);
+ case BO_SubAssign: DISPATCH(BinSubAssign, CompoundAssignOperator);
+ case BO_ShlAssign: DISPATCH(BinShlAssign, CompoundAssignOperator);
+ case BO_ShrAssign: DISPATCH(BinShrAssign, CompoundAssignOperator);
+ case BO_AndAssign: DISPATCH(BinAndAssign, CompoundAssignOperator);
+ case BO_OrAssign: DISPATCH(BinOrAssign, CompoundAssignOperator);
+ case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator);
+ case BO_Comma: DISPATCH(BinComma, BinaryOperator);
}
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
switch (UnOp->getOpcode()) {
default: assert(0 && "Unknown unary operator!");
- case UnaryOperator::PostInc: DISPATCH(UnaryPostInc, UnaryOperator);
- case UnaryOperator::PostDec: DISPATCH(UnaryPostDec, UnaryOperator);
- case UnaryOperator::PreInc: DISPATCH(UnaryPreInc, UnaryOperator);
- case UnaryOperator::PreDec: DISPATCH(UnaryPreDec, UnaryOperator);
- case UnaryOperator::AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator);
- case UnaryOperator::Deref: DISPATCH(UnaryDeref, UnaryOperator);
- case UnaryOperator::Plus: DISPATCH(UnaryPlus, UnaryOperator);
- case UnaryOperator::Minus: DISPATCH(UnaryMinus, UnaryOperator);
- case UnaryOperator::Not: DISPATCH(UnaryNot, UnaryOperator);
- case UnaryOperator::LNot: DISPATCH(UnaryLNot, UnaryOperator);
- case UnaryOperator::Real: DISPATCH(UnaryReal, UnaryOperator);
- case UnaryOperator::Imag: DISPATCH(UnaryImag, UnaryOperator);
- case UnaryOperator::Extension: DISPATCH(UnaryExtension, UnaryOperator);
- case UnaryOperator::OffsetOf: DISPATCH(UnaryOffsetOf, UnaryOperator);
+ case UO_PostInc: DISPATCH(UnaryPostInc, UnaryOperator);
+ case UO_PostDec: DISPATCH(UnaryPostDec, UnaryOperator);
+ case UO_PreInc: DISPATCH(UnaryPreInc, UnaryOperator);
+ case UO_PreDec: DISPATCH(UnaryPreDec, UnaryOperator);
+ case UO_AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator);
+ case UO_Deref: DISPATCH(UnaryDeref, UnaryOperator);
+ case UO_Plus: DISPATCH(UnaryPlus, UnaryOperator);
+ case UO_Minus: DISPATCH(UnaryMinus, UnaryOperator);
+ case UO_Not: DISPATCH(UnaryNot, UnaryOperator);
+ case UO_LNot: DISPATCH(UnaryLNot, UnaryOperator);
+ case UO_Real: DISPATCH(UnaryReal, UnaryOperator);
+ case UO_Imag: DISPATCH(UnaryImag, UnaryOperator);
+ case UO_Extension: DISPATCH(UnaryExtension, UnaryOperator);
}
}
@@ -163,7 +152,7 @@ public:
UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus)
UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot)
UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag)
- UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(OffsetOf)
+ UNARYOP_FALLBACK(Extension)
#undef UNARYOP_FALLBACK
// Base case, ignore it. :)
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 4c148e8..92e62a5 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -289,7 +289,18 @@ public:
L += R;
return L;
}
+
+ Qualifiers &operator-=(Qualifiers R) {
+ Mask = Mask & ~(R.Mask);
+ return *this;
+ }
+ /// \brief Compute the difference between two qualifier sets.
+ friend Qualifiers operator-(Qualifiers L, Qualifiers R) {
+ L -= R;
+ return L;
+ }
+
std::string getAsString() const;
std::string getAsString(const PrintingPolicy &Policy) const {
std::string Buffer;
@@ -399,7 +410,8 @@ enum CallingConv {
CC_C, // __attribute__((cdecl))
CC_X86StdCall, // __attribute__((stdcall))
CC_X86FastCall, // __attribute__((fastcall))
- CC_X86ThisCall // __attribute__((thiscall))
+ CC_X86ThisCall, // __attribute__((thiscall))
+ CC_X86Pascal // __attribute__((pascal))
};
@@ -787,12 +799,12 @@ private:
/// \brief Linkage of this type.
mutable unsigned CachedLinkage : 2;
- /// \brief FromPCH - Whether this type comes from a PCH file.
- mutable bool FromPCH : 1;
+ /// \brief FromAST - Whether this type comes from an AST file.
+ mutable bool FromAST : 1;
- /// \brief Set whether this type comes from a PCH file.
- void setFromPCH(bool V = true) const {
- FromPCH = V;
+ /// \brief Set whether this type comes from an AST file.
+ void setFromAST(bool V = true) const {
+ FromAST = V;
}
protected:
@@ -806,16 +818,15 @@ protected:
Type(TypeClass tc, QualType Canonical, bool dependent)
: CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
TC(tc), Dependent(dependent), LinkageKnown(false),
- CachedLinkage(NoLinkage), FromPCH(false) {}
- virtual ~Type() {}
- virtual void Destroy(ASTContext& C);
+ CachedLinkage(NoLinkage), FromAST(false) {}
+ virtual ~Type();
friend class ASTContext;
public:
TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); }
- /// \brief Whether this type comes from a PCH file.
- bool isFromPCH() const { return FromPCH; }
+ /// \brief Whether this type comes from an AST file.
+ bool isFromAST() const { return FromAST; }
bool isCanonicalUnqualified() const {
return CanonicalType.getTypePtr() == this;
@@ -824,14 +835,6 @@ public:
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.
- /// \brief Determines whether the type describes an object in memory.
- ///
- /// Note that this definition of object type corresponds to the C++
- /// definition of object type, which includes incomplete types, as
- /// opposed to the C definition (which does not include incomplete
- /// types).
- bool isObjectType() const;
-
/// isIncompleteType - Return true if this is an incomplete type.
/// A type that can describe objects, but which lacks information needed to
/// determine its size (e.g. void, or a fwd declared struct). Clients of this
@@ -906,6 +909,7 @@ public:
bool isFunctionPointerType() const;
bool isMemberPointerType() const;
bool isMemberFunctionPointerType() const;
+ bool isMemberDataPointerType() const;
bool isArrayType() const;
bool isConstantArrayType() const;
bool isIncompleteArrayType() const;
@@ -926,6 +930,7 @@ public:
bool isObjCQualifiedInterfaceType() const; // NSString<foo>
bool isObjCQualifiedIdType() const; // id<foo>
bool isObjCQualifiedClassType() const; // Class<foo>
+ bool isObjCObjectOrInterfaceType() const;
bool isObjCIdType() const; // id
bool isObjCClassType() const; // Class
bool isObjCSelType() const; // Class
@@ -952,10 +957,22 @@ public:
/// an objective pointer type for the purpose of GC'ability
bool hasObjCPointerRepresentation() const;
+ /// \brief Determine whether this type has an integer representation
+ /// of some sort, e.g., it is an integer type or a vector.
+ bool hasIntegerRepresentation() const;
+
+ /// \brief Determine whether this type has an signed integer representation
+ /// of some sort, e.g., it is an signed integer type or a vector.
+ bool hasSignedIntegerRepresentation() const;
+
+ /// \brief Determine whether this type has an unsigned integer representation
+ /// of some sort, e.g., it is an unsigned integer type or a vector.
+ bool hasUnsignedIntegerRepresentation() const;
+
/// \brief Determine whether this type has a floating-point representation
/// of some sort, e.g., it is a floating-point type or a vector thereof.
bool hasFloatingRepresentation() const;
-
+
// Type Checking Functions: Check to see if this type is structurally the
// specified type, ignoring typedefs and qualifiers, and return a pointer to
// the best type we can.
@@ -975,7 +992,8 @@ public:
/// type of a class template or class template partial specialization.
CXXRecordDecl *getAsCXXRecordDecl() const;
- // Member-template getAs<specific type>'. This scheme will eventually
+ // Member-template getAs<specific type>'. Look through sugar for
+ // an instance of <specific type>. This scheme will eventually
// replace the specific getAsXXXX methods above.
//
// There are some specializations of this member template listed
@@ -1035,8 +1053,8 @@ public:
void dump() const;
static bool classof(const Type *) { return true; }
- friend class PCHReader;
- friend class PCHWriter;
+ friend class ASTReader;
+ friend class ASTWriter;
};
template <> inline const TypedefType *Type::getAs() const {
@@ -1353,9 +1371,20 @@ protected:
virtual Linkage getLinkageImpl() const;
public:
-
QualType getPointeeType() const { return PointeeType; }
+ /// Returns true if the member type (i.e. the pointee type) is a
+ /// function type rather than a data-member type.
+ bool isMemberFunctionPointer() const {
+ return PointeeType->isFunctionProtoType();
+ }
+
+ /// Returns true if the member type (i.e. the pointee type) is a
+ /// data type rather than a function type.
+ bool isMemberDataPointer() const {
+ return !PointeeType->isFunctionProtoType();
+ }
+
const Type *getClass() const { return Class; }
bool isSugared() const { return false; }
@@ -1454,6 +1483,17 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
+
+ /// \brief Determine the number of bits required to address a member of
+ // an array with the given element type and number of elements.
+ static unsigned getNumAddressingBits(ASTContext &Context,
+ QualType ElementType,
+ const llvm::APInt &NumElements);
+
+ /// \brief Determine the maximum number of active bits that an array's size
+ /// can require, which limits the maximum size of the array.
+ static unsigned getMaxSizeBits(ASTContext &Context);
+
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getElementType(), getSize(),
getSizeModifier(), getIndexTypeCVRQualifiers());
@@ -1533,7 +1573,6 @@ class VariableArrayType : public ArrayType {
: ArrayType(VariableArray, et, can, sm, tq),
SizeExpr((Stmt*) e), Brackets(brackets) {}
friend class ASTContext; // ASTContext creates these.
- virtual void Destroy(ASTContext& C);
public:
Expr *getSizeExpr() const {
@@ -1592,7 +1631,6 @@ class DependentSizedArrayType : public ArrayType {
: ArrayType(DependentSizedArray, et, can, sm, tq),
Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) {}
friend class ASTContext; // ASTContext creates these.
- virtual void Destroy(ASTContext& C);
public:
Expr *getSizeExpr() const {
@@ -1646,7 +1684,6 @@ class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
Context(Context), SizeExpr(SizeExpr), ElementType(ElementType),
loc(loc) {}
friend class ASTContext;
- virtual void Destroy(ASTContext& C);
public:
Expr *getSizeExpr() const { return SizeExpr; }
@@ -1844,13 +1881,13 @@ class FunctionType : public Type {
// * FunctionNoProtoType::Profile
// * FunctionProtoType::Profile
// * TypePrinter::PrintFunctionProto
- // * PCH read and write
+ // * AST read and write
// * Codegen
class ExtInfo {
public:
// Constructor with no defaults. Use this when you know that you
- // have all the elements (when reading a PCH file for example).
+ // have all the elements (when reading an AST file for example).
ExtInfo(bool noReturn, unsigned regParm, CallingConv cc) :
NoReturn(noReturn), RegParm(regParm), CC(cc) {}
@@ -1892,7 +1929,7 @@ class FunctionType : public Type {
// The value passed to __attribute__((regparm(x)))
unsigned RegParm;
// The calling convention as specified via
- // __attribute__((cdecl|stdcall|fastcall|thiscall))
+ // __attribute__((cdecl|stdcall|fastcall|thiscall|pascal))
CallingConv CC;
};
@@ -2259,14 +2296,9 @@ public:
};
class TagType : public Type {
- /// Stores the TagDecl associated with this type. The decl will
- /// point to the TagDecl that actually defines the entity (or is a
- /// definition in progress), if there is such a definition. The
- /// single-bit value will be non-zero when this tag is in the
- /// process of being defined.
- mutable llvm::PointerIntPair<TagDecl *, 1> decl;
- friend class ASTContext;
- friend class TagDecl;
+ /// Stores the TagDecl associated with this type. The decl may point to any
+ /// TagDecl that declares the entity.
+ TagDecl * decl;
protected:
TagType(TypeClass TC, const TagDecl *D, QualType can);
@@ -2274,12 +2306,11 @@ protected:
virtual Linkage getLinkageImpl() const;
public:
- TagDecl *getDecl() const { return decl.getPointer(); }
+ TagDecl *getDecl() const;
/// @brief Determines whether this type is in the process of being
/// defined.
- bool isBeingDefined() const { return decl.getInt(); }
- void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
+ bool isBeingDefined() const;
static bool classof(const Type *T) {
return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
@@ -2468,8 +2499,6 @@ class TemplateSpecializationType
const TemplateArgument *Args,
unsigned NumArgs, QualType Canon);
- virtual void Destroy(ASTContext& C);
-
friend class ASTContext; // ASTContext creates these
public:
@@ -2574,9 +2603,8 @@ class InjectedClassNameType : public Type {
QualType InjectedType;
friend class ASTContext; // ASTContext creates these.
- friend class TagDecl; // TagDecl mutilates the Decl
- friend class PCHReader; // FIXME: ASTContext::getInjectedClassNameType is not
- // currently suitable for PCH reading, too much
+ friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
+ // currently suitable for AST reading, too much
// interdependencies.
InjectedClassNameType(CXXRecordDecl *D, QualType TST)
: Type(InjectedClassName, QualType(), true),
@@ -2592,7 +2620,7 @@ public:
return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
}
- CXXRecordDecl *getDecl() const { return Decl; }
+ CXXRecordDecl *getDecl() const;
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2836,8 +2864,6 @@ class DependentTemplateSpecializationType :
const TemplateArgument *Args,
QualType Canon);
- virtual void Destroy(ASTContext& C);
-
friend class ASTContext; // ASTContext creates these
public:
@@ -3014,8 +3040,6 @@ class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
: ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {}
public:
- void Destroy(ASTContext& C); // key function
-
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID,
QualType Base,
@@ -3049,8 +3073,6 @@ class ObjCInterfaceType : public ObjCObjectType {
Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
friend class ASTContext; // ASTContext creates these.
public:
- void Destroy(ASTContext& C); // key function
-
/// getDecl - Get the declaration of this interface.
ObjCInterfaceDecl *getDecl() const { return Decl; }
@@ -3103,8 +3125,6 @@ protected:
virtual Linkage getLinkageImpl() const;
public:
- void Destroy(ASTContext& C);
-
/// getPointeeType - Gets the type pointed to by this ObjC pointer.
/// The result will always be an ObjCObjectType or sugar thereof.
QualType getPointeeType() const { return PointeeType; }
@@ -3486,7 +3506,13 @@ inline bool Type::isMemberPointerType() const {
}
inline bool Type::isMemberFunctionPointerType() const {
if (const MemberPointerType* T = getAs<MemberPointerType>())
- return T->getPointeeType()->isFunctionType();
+ return T->isMemberFunctionPointer();
+ else
+ return false;
+}
+inline bool Type::isMemberDataPointerType() const {
+ if (const MemberPointerType* T = getAs<MemberPointerType>())
+ return T->isMemberDataPointer();
else
return false;
}
@@ -3523,6 +3549,11 @@ inline bool Type::isObjCObjectPointerType() const {
inline bool Type::isObjCObjectType() const {
return isa<ObjCObjectType>(CanonicalType);
}
+inline bool Type::isObjCObjectOrInterfaceType() const {
+ return isa<ObjCInterfaceType>(CanonicalType) ||
+ isa<ObjCObjectType>(CanonicalType);
+}
+
inline bool Type::isObjCQualifiedIdType() const {
if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
return OPT->isObjCQualifiedIdType();
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 842c068..f1c64bd 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -341,6 +341,10 @@ private:
template <class Base, class Derived, class TypeClass>
class InheritingConcreteTypeLoc : public Base {
public:
+ static bool classofType(const Type *Ty) {
+ return TypeClass::classof(Ty);
+ }
+
static bool classof(const TypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
index 1a050d2..7cf0d5e 100644
--- a/include/clang/AST/TypeOrdering.h
+++ b/include/clang/AST/TypeOrdering.h
@@ -17,6 +17,7 @@
#define LLVM_CLANG_TYPE_ORDERING_H
#include "clang/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
#include <functional>
namespace clang {
@@ -51,6 +52,26 @@ namespace llvm {
return LHS == RHS;
}
};
+
+ template<> struct DenseMapInfo<clang::CanQualType> {
+ static inline clang::CanQualType getEmptyKey() {
+ return clang::CanQualType();
+ }
+
+ static inline clang::CanQualType getTombstoneKey() {
+ using clang::CanQualType;
+ return CanQualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
+ }
+
+ static unsigned getHashValue(clang::CanQualType Val) {
+ return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
+ ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
+ }
+
+ static bool isEqual(clang::CanQualType LHS, clang::CanQualType RHS) {
+ return LHS == RHS;
+ }
+ };
}
#endif
OpenPOWER on IntegriCloud