aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTContext.h46
-rw-r--r--include/clang/AST/ASTDiagnostic.h22
-rw-r--r--include/clang/AST/ASTImporter.h234
-rw-r--r--include/clang/AST/Attr.h78
-rw-r--r--include/clang/AST/CXXInheritance.h11
-rw-r--r--include/clang/AST/Decl.h377
-rw-r--r--include/clang/AST/DeclBase.h86
-rw-r--r--include/clang/AST/DeclCXX.h492
-rw-r--r--include/clang/AST/DeclObjC.h70
-rw-r--r--include/clang/AST/DeclTemplate.h53
-rw-r--r--include/clang/AST/DeclarationName.h12
-rw-r--r--include/clang/AST/Expr.h19
-rw-r--r--include/clang/AST/ExprCXX.h418
-rw-r--r--include/clang/AST/ExprObjC.h10
-rw-r--r--include/clang/AST/Stmt.h93
-rw-r--r--include/clang/AST/StmtCXX.h27
-rw-r--r--include/clang/AST/StmtNodes.def9
-rw-r--r--include/clang/AST/StmtVisitor.h1
-rw-r--r--include/clang/AST/Type.h170
-rw-r--r--include/clang/AST/TypeNodes.def5
-rw-r--r--include/clang/AST/UnresolvedSet.h116
21 files changed, 1512 insertions, 837 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index e5429bec143c..2ed9fd708018 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -27,6 +27,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Allocator.h"
#include <vector>
@@ -46,6 +47,7 @@ namespace clang {
class SourceManager;
class TargetInfo;
// Decls
+ class DeclContext;
class CXXMethodDecl;
class CXXRecordDecl;
class Decl;
@@ -502,7 +504,8 @@ public:
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
- QualType getVectorType(QualType VectorType, unsigned NumElts);
+ QualType getVectorType(QualType VectorType, unsigned NumElts,
+ bool AltiVec, bool IsPixel);
/// getExtVectorType - Return the unique reference to an extended vector type
/// of the specified element type and size. VectorType must be a built-in
@@ -534,11 +537,11 @@ public:
/// getTypeDeclType - Return the unique reference to the type for
/// the specified type declaration.
- QualType getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl=0);
+ QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl* PrevDecl=0);
/// getTypedefType - Return the unique reference to the type for the
/// specified typename decl.
- QualType getTypedefType(TypedefDecl *Decl);
+ QualType getTypedefType(const TypedefDecl *Decl);
QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
QualType Replacement);
@@ -835,13 +838,23 @@ public:
return getTypeInfo(T).second;
}
+ /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in
+ /// characters. This method does not work on incomplete types.
+ CharUnits getTypeAlignInChars(QualType T);
+ CharUnits getTypeAlignInChars(const Type *T);
+
/// getPreferredTypeAlign - Return the "preferred" alignment of the specified
/// type for the current target in bits. This can be different than the ABI
/// alignment in cases where it is beneficial for performance to overalign
/// a data type.
unsigned getPreferredTypeAlign(const Type *T);
- unsigned getDeclAlignInBytes(const Decl *D, bool RefAsPointee = false);
+ /// getDeclAlign - Return a conservative estimate of the alignment of
+ /// the specified decl. Note that bitfields do not have a valid alignment, so
+ /// this method will assert on them.
+ /// If @p RefAsPointee, references are treated like their underlying type
+ /// (for alignof), else they're treated like pointers (for CodeGen).
+ CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false);
/// getASTRecordLayout - Get or compute information about the layout of the
/// specified record (struct/union/class), which indicates its size and field
@@ -878,7 +891,7 @@ public:
unsigned CountSynthesizedIvars(const ObjCInterfaceDecl *OI);
unsigned CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD);
void CollectInheritedProtocols(const Decl *CDecl,
- llvm::SmallVectorImpl<ObjCProtocolDecl*> &Protocols);
+ llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
//===--------------------------------------------------------------------===//
// Type Operators
@@ -960,6 +973,20 @@ public:
NestedNameSpecifier *
getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS);
+ /// \brief Retrieves the canonical representation of the given
+ /// calling convention.
+ CallingConv getCanonicalCallConv(CallingConv CC) {
+ if (CC == CC_C)
+ return CC_Default;
+ return CC;
+ }
+
+ /// \brief Determines whether two calling conventions name the same
+ /// calling convention.
+ bool isSameCallConv(CallingConv lcc, CallingConv rcc) {
+ return (getCanonicalCallConv(lcc) == getCanonicalCallConv(rcc));
+ }
+
/// \brief Retrieves the "canonical" template name that refers to a
/// given template.
///
@@ -1187,6 +1214,15 @@ private:
const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
+
+private:
+ // FIXME: This currently contains the set of StoredDeclMaps used
+ // by DeclContext objects. This probably should not be in ASTContext,
+ // but we include it here so that ASTContext can quickly deallocate them.
+ std::vector<void*> SDMs;
+ friend class DeclContext;
+ void *CreateStoredDeclsMap();
+ void ReleaseDeclContextMaps();
};
/// @brief Utility function for constructing a nullary selector.
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index abd36f7e5f0f..2d314913469e 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -1,4 +1,4 @@
-//===--- DiagnosticAST.h - Diagnostics for the AST library ------*- C++ -*-===//
+//===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -22,6 +22,26 @@ namespace clang {
NUM_BUILTIN_AST_DIAGNOSTICS
};
} // end namespace diag
+
+ /// \brief Diagnostic argument formatting function for diagnostics that
+ /// involve AST nodes.
+ ///
+ /// This function formats diagnostic arguments for various AST nodes,
+ /// including types, declaration names, nested name specifiers, and
+ /// declaration contexts, into strings that can be printed as part of
+ /// diagnostics. It is meant to be used as the argument to
+ /// \c Diagnostic::SetArgToStringFn(), where the cookie is an \c ASTContext
+ /// pointer.
+ void FormatASTNodeDiagnosticArgument(Diagnostic::ArgumentKind Kind,
+ intptr_t Val,
+ const char *Modifier,
+ unsigned ModLen,
+ const char *Argument,
+ unsigned ArgLen,
+ const Diagnostic::ArgumentValue *PrevArgs,
+ unsigned NumPrevArgs,
+ llvm::SmallVectorImpl<char> &Output,
+ void *Cookie);
} // end namespace clang
#endif
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
new file mode 100644
index 000000000000..f5f11ca83662
--- /dev/null
+++ b/include/clang/AST/ASTImporter.h
@@ -0,0 +1,234 @@
+//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ASTImporter class which imports AST nodes from one
+// context into another context.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
+#define LLVM_CLANG_AST_ASTIMPORTER_H
+
+#include "clang/AST/Type.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+ class ASTContext;
+ class Decl;
+ class DeclContext;
+ class Diagnostic;
+ class Expr;
+ class FileManager;
+ class IdentifierInfo;
+ class NestedNameSpecifier;
+ class Stmt;
+ class TypeSourceInfo;
+
+ /// \brief Imports selected nodes from one AST context into another context,
+ /// merging AST nodes where appropriate.
+ class ASTImporter {
+ public:
+ typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
+
+ private:
+ /// \brief The contexts we're importing to and from.
+ ASTContext &ToContext, &FromContext;
+
+ /// \brief The file managers we're importing to and from.
+ FileManager &ToFileManager, &FromFileManager;
+
+ /// \brief The diagnostics object that we should use to emit diagnostics.
+ Diagnostic &Diags;
+
+ /// \brief Mapping from the already-imported types in the "from" context
+ /// to the corresponding types in the "to" context.
+ llvm::DenseMap<Type *, Type *> ImportedTypes;
+
+ /// \brief Mapping from the already-imported declarations in the "from"
+ /// context to the corresponding declarations in the "to" context.
+ llvm::DenseMap<Decl *, Decl *> ImportedDecls;
+
+ /// \brief Mapping from the already-imported statements in the "from"
+ /// context to the corresponding statements in the "to" context.
+ llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
+
+ /// \brief Mapping from the already-imported FileIDs in the "from" source
+ /// manager to the corresponding FileIDs in the "to" source manager.
+ llvm::DenseMap<unsigned, FileID> ImportedFileIDs;
+
+ /// \brief Imported, anonymous tag declarations that are missing their
+ /// corresponding typedefs.
+ llvm::SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
+
+ /// \brief Declaration (from, to) pairs that are known not to be equivalent
+ /// (which we have already complained about).
+ NonEquivalentDeclSet NonEquivalentDecls;
+
+ public:
+ ASTImporter(Diagnostic &Diags,
+ ASTContext &ToContext, FileManager &ToFileManager,
+ ASTContext &FromContext, FileManager &FromFileManager);
+
+ virtual ~ASTImporter();
+
+ /// \brief Import the given type from the "from" context into the "to"
+ /// context.
+ ///
+ /// \returns the equivalent type in the "to" context, or a NULL type if
+ /// an error occurred.
+ QualType Import(QualType FromT);
+
+ /// \brief Import the given type source information from the
+ /// "from" context into the "to" context.
+ ///
+ /// \returns the equivalent type source information in the "to"
+ /// context, or NULL if an error occurred.
+ TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
+
+ /// \brief Import the given declaration from the "from" context into the
+ /// "to" context.
+ ///
+ /// \returns the equivalent declaration in the "to" context, or a NULL type
+ /// if an error occurred.
+ Decl *Import(Decl *FromD);
+
+ /// \brief Import the given declaration context from the "from"
+ /// AST context into the "to" AST context.
+ ///
+ /// \returns the equivalent declaration context in the "to"
+ /// context, or a NULL type if an error occurred.
+ DeclContext *ImportContext(DeclContext *FromDC);
+
+ /// \brief Import the given expression from the "from" context into the
+ /// "to" context.
+ ///
+ /// \returns the equivalent expression in the "to" context, or NULL if
+ /// an error occurred.
+ Expr *Import(Expr *FromE);
+
+ /// \brief Import the given statement from the "from" context into the
+ /// "to" context.
+ ///
+ /// \returns the equivalent statement in the "to" context, or NULL if
+ /// an error occurred.
+ Stmt *Import(Stmt *FromS);
+
+ /// \brief Import the given nested-name-specifier from the "from"
+ /// context into the "to" context.
+ ///
+ /// \returns the equivalent nested-name-specifier in the "to"
+ /// context, or NULL if an error occurred.
+ NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
+
+ /// \brief Import the given source location from the "from" context into
+ /// the "to" context.
+ ///
+ /// \returns the equivalent source location in the "to" context, or an
+ /// invalid source location if an error occurred.
+ SourceLocation Import(SourceLocation FromLoc);
+
+ /// \brief Import the given source range from the "from" context into
+ /// the "to" context.
+ ///
+ /// \returns the equivalent source range in the "to" context, or an
+ /// invalid source location if an error occurred.
+ SourceRange Import(SourceRange FromRange);
+
+ /// \brief Import the given declaration name from the "from"
+ /// context into the "to" context.
+ ///
+ /// \returns the equivalent declaration name in the "to" context,
+ /// or an empty declaration name if an error occurred.
+ DeclarationName Import(DeclarationName FromName);
+
+ /// \brief Import the given identifier from the "from" context
+ /// into the "to" context.
+ ///
+ /// \returns the equivalent identifier in the "to" context.
+ IdentifierInfo *Import(IdentifierInfo *FromId);
+
+ /// \brief Import the given file ID from the "from" context into the
+ /// "to" context.
+ ///
+ /// \returns the equivalent file ID in the source manager of the "to"
+ /// context.
+ FileID Import(FileID);
+
+ /// \brief Cope with a name conflict when importing a declaration into the
+ /// given context.
+ ///
+ /// This routine is invoked whenever there is a name conflict while
+ /// importing a declaration. The returned name will become the name of the
+ /// imported declaration. By default, the returned name is the same as the
+ /// original name, leaving the conflict unresolve such that name lookup
+ /// for this name is likely to find an ambiguity later.
+ ///
+ /// Subclasses may override this routine to resolve the conflict, e.g., by
+ /// renaming the declaration being imported.
+ ///
+ /// \param Name the name of the declaration being imported, which conflicts
+ /// with other declarations.
+ ///
+ /// \param DC the declaration context (in the "to" AST context) in which
+ /// the name is being imported.
+ ///
+ /// \param IDNS the identifier namespace in which the name will be found.
+ ///
+ /// \param Decls the set of declarations with the same name as the
+ /// declaration being imported.
+ ///
+ /// \param NumDecls the number of conflicting declarations in \p Decls.
+ ///
+ /// \returns the name that the newly-imported declaration should have.
+ virtual DeclarationName HandleNameConflict(DeclarationName Name,
+ DeclContext *DC,
+ unsigned IDNS,
+ NamedDecl **Decls,
+ unsigned NumDecls);
+
+ /// \brief Retrieve the context that AST nodes are being imported into.
+ ASTContext &getToContext() const { return ToContext; }
+
+ /// \brief Retrieve the context that AST nodes are being imported from.
+ ASTContext &getFromContext() const { return FromContext; }
+
+ /// \brief Retrieve the file manager that AST nodes are being imported into.
+ FileManager &getToFileManager() const { return ToFileManager; }
+
+ /// \brief Retrieve the file manager that AST nodes are being imported from.
+ FileManager &getFromFileManager() const { return FromFileManager; }
+
+ /// \brief Retrieve the diagnostic formatter.
+ Diagnostic &getDiags() const { return Diags; }
+
+ /// \brief Report a diagnostic in the "to" context.
+ DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
+
+ /// \brief Report a diagnostic in the "from" context.
+ DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
+
+ /// \brief Return the set of declarations that we know are not equivalent.
+ NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
+
+ /// \brief Note that we have imported the "from" declaration by mapping it
+ /// to the (potentially-newly-created) "to" declaration.
+ ///
+ /// \returns \p To
+ Decl *Imported(Decl *From, Decl *To);
+
+ /// \brief Determine whether the given types are structurally
+ /// equivalent.
+ bool IsStructurallyEquivalent(QualType From, QualType To);
+ };
+}
+
+#endif // LLVM_CLANG_AST_ASTIMPORTER_H
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 03ab0f07020b..37225907c6de 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -18,7 +18,6 @@
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <cstring>
-#include <string>
#include <algorithm>
using llvm::dyn_cast;
@@ -96,7 +95,8 @@ public:
FIRST_TARGET_ATTRIBUTE,
DLLExport,
DLLImport,
- MSP430Interrupt
+ MSP430Interrupt,
+ X86ForceAlignArgPointer
};
private:
@@ -119,8 +119,7 @@ protected:
assert(Next == 0 && "Destroy didn't work");
}
public:
-
- void Destroy(ASTContext &C);
+ virtual void Destroy(ASTContext &C);
/// \brief Whether this attribute should be merged to new
/// declarations.
@@ -156,6 +155,18 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *) { return true; }
};
+
+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 { \
@@ -213,12 +224,12 @@ public:
static bool classof(const AlignedAttr *A) { return true; }
};
-class AnnotateAttr : public Attr {
- std::string Annotation;
+class AnnotateAttr : public AttrWithString {
public:
- AnnotateAttr(llvm::StringRef ann) : Attr(Annotate), Annotation(ann) {}
+ AnnotateAttr(ASTContext &C, llvm::StringRef ann)
+ : AttrWithString(Annotate, C, ann) {}
- const std::string& getAnnotation() const { return Annotation; }
+ llvm::StringRef getAnnotation() const { return getString(); }
virtual Attr* clone(ASTContext &C) const;
@@ -229,12 +240,12 @@ public:
static bool classof(const AnnotateAttr *A) { return true; }
};
-class AsmLabelAttr : public Attr {
- std::string Label;
+class AsmLabelAttr : public AttrWithString {
public:
- AsmLabelAttr(llvm::StringRef L) : Attr(AsmLabel), Label(L) {}
+ AsmLabelAttr(ASTContext &C, llvm::StringRef L)
+ : AttrWithString(AsmLabel, C, L) {}
- const std::string& getLabel() const { return Label; }
+ llvm::StringRef getLabel() const { return getString(); }
virtual Attr* clone(ASTContext &C) const;
@@ -247,12 +258,12 @@ public:
DEF_SIMPLE_ATTR(AlwaysInline);
-class AliasAttr : public Attr {
- std::string Aliasee;
+class AliasAttr : public AttrWithString {
public:
- AliasAttr(llvm::StringRef aliasee) : Attr(Alias), Aliasee(aliasee) {}
+ AliasAttr(ASTContext &C, llvm::StringRef aliasee)
+ : AttrWithString(Alias, C, aliasee) {}
- const std::string& getAliasee() const { return Aliasee; }
+ llvm::StringRef getAliasee() const { return getString(); }
virtual Attr *clone(ASTContext &C) const;
@@ -321,12 +332,12 @@ DEF_SIMPLE_ATTR(AnalyzerNoReturn);
DEF_SIMPLE_ATTR(Deprecated);
DEF_SIMPLE_ATTR(Final);
-class SectionAttr : public Attr {
- std::string Name;
+class SectionAttr : public AttrWithString {
public:
- SectionAttr(llvm::StringRef N) : Attr(Section), Name(N) {}
+ SectionAttr(ASTContext &C, llvm::StringRef N)
+ : AttrWithString(Section, C, N) {}
- const std::string& getName() const { return Name; }
+ llvm::StringRef getName() const { return getString(); }
virtual Attr *clone(ASTContext &C) const;
@@ -350,19 +361,9 @@ class NonNullAttr : public Attr {
unsigned* ArgNums;
unsigned Size;
public:
- NonNullAttr(unsigned* arg_nums = 0, unsigned size = 0) : Attr(NonNull),
- ArgNums(0), Size(0) {
+ NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
- if (size == 0) return;
- assert(arg_nums);
- ArgNums = new unsigned[size];
- Size = size;
- memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
- }
-
- virtual ~NonNullAttr() {
- delete [] ArgNums;
- }
+ virtual void Destroy(ASTContext &C);
typedef const unsigned *iterator;
iterator begin() const { return ArgNums; }
@@ -379,15 +380,14 @@ public:
static bool classof(const NonNullAttr *A) { return true; }
};
-class FormatAttr : public Attr {
- std::string Type;
+class FormatAttr : public AttrWithString {
int formatIdx, firstArg;
public:
- FormatAttr(llvm::StringRef type, int idx, int first) : Attr(Format),
- Type(type), formatIdx(idx), firstArg(first) {}
+ FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
+ : AttrWithString(Format, C, type), formatIdx(idx), firstArg(first) {}
- const std::string& getType() const { return Type; }
- void setType(llvm::StringRef type) { Type = type; }
+ llvm::StringRef getType() const { return getString(); }
+ void setType(ASTContext &C, llvm::StringRef type);
int getFormatIdx() const { return formatIdx; }
int getFirstArg() const { return firstArg; }
@@ -570,6 +570,8 @@ public:
static bool classof(const MSP430InterruptAttr *A) { return true; }
};
+DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
+
#undef DEF_SIMPLE_ATTR
} // end namespace clang
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 1491b1edbbac..79a3022ee014 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -161,7 +161,8 @@ class CXXBasePaths {
void ComputeDeclsFound();
public:
- typedef std::list<CXXBasePath>::const_iterator paths_iterator;
+ typedef std::list<CXXBasePath>::iterator paths_iterator;
+ typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
typedef NamedDecl **decl_iterator;
/// BasePaths - Construct a new BasePaths structure to record the
@@ -175,8 +176,10 @@ public:
~CXXBasePaths() { delete [] DeclsFound; }
- paths_iterator begin() const { return Paths.begin(); }
- paths_iterator end() const { return Paths.end(); }
+ paths_iterator begin() { return Paths.begin(); }
+ paths_iterator end() { return Paths.end(); }
+ const_paths_iterator begin() const { return Paths.begin(); }
+ const_paths_iterator end() const { return Paths.end(); }
CXXBasePath& front() { return Paths.front(); }
const CXXBasePath& front() const { return Paths.front(); }
@@ -206,7 +209,7 @@ public:
const RecordType* getDetectedVirtual() const {
return DetectedVirtual;
}
-
+
/// \brief Retrieve the type from which this base-paths search
/// began
CXXRecordDecl *getOrigin() const { return Origin; }
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 6d52b2b2bc91..07442896dc4b 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -19,6 +19,7 @@
#include "clang/AST/Redeclarable.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/Linkage.h"
namespace clang {
class CXXTemporary;
@@ -75,8 +76,9 @@ public:
static TranslationUnitDecl *Create(ASTContext &C);
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == TranslationUnit; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TranslationUnitDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == TranslationUnit; }
static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
}
@@ -194,23 +196,6 @@ public:
return DC->isRecord();
}
- /// \brief Describes the different kinds of linkage
- /// (C++ [basic.link], C99 6.2.2) that an entity may have.
- enum Linkage {
- /// \brief No linkage, which means that the entity is unique and
- /// can only be referred to from within its scope.
- NoLinkage = 0,
-
- /// \brief Internal linkage, which indicates that the entity can
- /// be referred to from within the translation unit (but not other
- /// translation units).
- InternalLinkage,
-
- /// \brief External linkage, which indicates that the entity can
- /// be referred to from other translation units.
- ExternalLinkage
- };
-
/// \brief Determine what kind of linkage this entity has.
Linkage getLinkage() const;
@@ -221,10 +206,9 @@ public:
return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
}
- static bool classof(const Decl *D) {
- return D->getKind() >= NamedFirst && D->getKind() <= NamedLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamedDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= NamedFirst && K <= NamedLast; }
};
/// NamespaceDecl - Represent a C++ namespace.
@@ -301,8 +285,9 @@ public:
void setRBracLoc(SourceLocation RBrace) { RBracLoc = RBrace; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == Namespace; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamespaceDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Namespace; }
static DeclContext *castToDeclContext(const NamespaceDecl *D) {
return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D));
}
@@ -326,10 +311,9 @@ public:
void setType(QualType newType) { DeclType = newType; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= ValueFirst && D->getKind() <= ValueLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ValueDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= ValueFirst && K <= ValueLast; }
};
/// \brief Represents a ValueDecl that came out of a declarator.
@@ -349,10 +333,11 @@ public:
SourceLocation getTypeSpecStartLoc() const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= DeclaratorFirst && D->getKind() <= DeclaratorLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const DeclaratorDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= DeclaratorFirst && K <= DeclaratorLast;
+ }
};
/// \brief Structure used to store a statement, the constant value to
@@ -474,14 +459,142 @@ public:
SourceLocation L, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, StorageClass S);
- virtual ~VarDecl();
virtual void Destroy(ASTContext& C);
+ virtual ~VarDecl();
+
+ virtual SourceRange getSourceRange() const;
StorageClass getStorageClass() const { return (StorageClass)SClass; }
void setStorageClass(StorageClass SC) { SClass = SC; }
- virtual SourceRange getSourceRange() const;
+ void setThreadSpecified(bool T) { ThreadSpecified = T; }
+ bool isThreadSpecified() const {
+ return ThreadSpecified;
+ }
+
+ /// hasLocalStorage - Returns true if a variable with function scope
+ /// is a non-static local variable.
+ bool hasLocalStorage() const {
+ if (getStorageClass() == None)
+ return !isFileVarDecl();
+
+ // Return true for: Auto, Register.
+ // Return false for: Extern, Static, PrivateExtern.
+
+ return getStorageClass() <= Register;
+ }
+
+ /// hasExternStorage - Returns true if a variable has extern or
+ /// __private_extern__ storage.
+ bool hasExternalStorage() const {
+ return getStorageClass() == Extern || getStorageClass() == PrivateExtern;
+ }
+
+ /// hasGlobalStorage - Returns true for all variables that do not
+ /// have local storage. This includs all global variables as well
+ /// as static variables declared within a function.
+ bool hasGlobalStorage() const { return !hasLocalStorage(); }
+
+ /// \brief Determines whether this variable is a variable with
+ /// external, C linkage.
+ bool isExternC() const;
+
+ /// isBlockVarDecl - Returns true for local variable declarations. Note that
+ /// this includes static variables inside of functions.
+ ///
+ /// void foo() { int x; static int y; extern int z; }
+ ///
+ bool isBlockVarDecl() const {
+ if (getKind() != Decl::Var)
+ return false;
+ if (const DeclContext *DC = getDeclContext())
+ return DC->getLookupContext()->isFunctionOrMethod();
+ return false;
+ }
+
+ /// \brief Determines whether this is a static data member.
+ ///
+ /// This will only be true in C++, and applies to, e.g., the
+ /// variable 'x' in:
+ /// \code
+ /// struct S {
+ /// static int x;
+ /// };
+ /// \endcode
+ bool isStaticDataMember() const {
+ // If it wasn't static, it would be a FieldDecl.
+ return getDeclContext()->isRecord();
+ }
+
+ virtual VarDecl *getCanonicalDecl();
+ const VarDecl *getCanonicalDecl() const {
+ return const_cast<VarDecl*>(this)->getCanonicalDecl();
+ }
+
+ enum DefinitionKind {
+ DeclarationOnly, ///< This declaration is only a declaration.
+ TentativeDefinition, ///< This declaration is a tentative definition.
+ Definition ///< This declaration is definitely a definition.
+ };
+
+ /// \brief Check whether this declaration is a definition. If this could be
+ /// a tentative definition (in C), don't check whether there's an overriding
+ /// definition.
+ DefinitionKind isThisDeclarationADefinition() const;
+
+ /// \brief Get the tentative definition that acts as the real definition in
+ /// a TU. Returns null if there is a proper definition available.
+ VarDecl *getActingDefinition();
+ const VarDecl *getActingDefinition() const {
+ return const_cast<VarDecl*>(this)->getActingDefinition();
+ }
+
+ /// \brief Determine whether this is a tentative definition of a
+ /// variable in C.
+ bool isTentativeDefinitionNow() const;
+
+ /// \brief Get the real (not just tentative) definition for this declaration.
+ VarDecl *getDefinition();
+ const VarDecl *getDefinition() const {
+ return const_cast<VarDecl*>(this)->getDefinition();
+ }
+
+ /// \brief Determine whether this is or was instantiated from an out-of-line
+ /// definition of a static data member.
+ bool isOutOfLine() const;
+
+ /// \brief If this is a static data member, find its out-of-line definition.
+ VarDecl *getOutOfLineDefinition();
+
+ /// isFileVarDecl - Returns true for file scoped variable declaration.
+ 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 (isStaticDataMember())
+ return true;
+
+ return false;
+ }
+
+ /// getAnyInitializer - Get the initializer for this variable, no matter which
+ /// declaration it is attached to.
+ const Expr *getAnyInitializer() const {
+ const VarDecl *D;
+ return getAnyInitializer(D);
+ }
+ /// getAnyInitializer - Get the initializer for this variable, no matter which
+ /// declaration it is attached to. Also get that declaration.
+ const Expr *getAnyInitializer(const VarDecl *&D) const;
+
+ bool hasInit() const {
+ return !Init.isNull();
+ }
const Expr *getInit() const {
if (Init.isNull())
return 0;
@@ -521,7 +634,7 @@ public:
return StmtPtr;
}
- void setInit(ASTContext &C, Expr *I);
+ void setInit(Expr *I);
EvaluatedStmt *EnsureEvaluatedStmt() const {
EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
@@ -614,17 +727,6 @@ public:
Eval->IsICE = IsICE;
}
- /// \brief Retrieve the definition of this variable, which may come
- /// from a previous declaration. Def will be set to the VarDecl that
- /// contains the initializer, and the result will be that
- /// initializer.
- const Expr *getDefinition(const VarDecl *&Def) const;
-
- void setThreadSpecified(bool T) { ThreadSpecified = T; }
- bool isThreadSpecified() const {
- return ThreadSpecified;
- }
-
void setCXXDirectInitializer(bool T) { HasCXXDirectInit = T; }
/// hasCXXDirectInitializer - If true, the initializer was a direct
@@ -648,67 +750,6 @@ public:
void setDeclaredInCondition(bool InCondition) {
DeclaredInCondition = InCondition;
}
-
- virtual VarDecl *getCanonicalDecl();
- const VarDecl *getCanonicalDecl() const {
- return const_cast<VarDecl*>(this)->getCanonicalDecl();
- }
-
- /// hasLocalStorage - Returns true if a variable with function scope
- /// is a non-static local variable.
- bool hasLocalStorage() const {
- if (getStorageClass() == None)
- return !isFileVarDecl();
-
- // Return true for: Auto, Register.
- // Return false for: Extern, Static, PrivateExtern.
-
- return getStorageClass() <= Register;
- }
-
- /// hasExternStorage - Returns true if a variable has extern or
- /// __private_extern__ storage.
- bool hasExternalStorage() const {
- return getStorageClass() == Extern || getStorageClass() == PrivateExtern;
- }
-
- /// hasGlobalStorage - Returns true for all variables that do not
- /// have local storage. This includs all global variables as well
- /// as static variables declared within a function.
- bool hasGlobalStorage() const { return !hasLocalStorage(); }
-
- /// isBlockVarDecl - Returns true for local variable declarations. Note that
- /// this includes static variables inside of functions.
- ///
- /// void foo() { int x; static int y; extern int z; }
- ///
- bool isBlockVarDecl() const {
- if (getKind() != Decl::Var)
- return false;
- if (const DeclContext *DC = getDeclContext())
- return DC->getLookupContext()->isFunctionOrMethod();
- return false;
- }
-
- /// \brief Determines whether this is a static data member.
- ///
- /// This will only be true in C++, and applies to, e.g., the
- /// variable 'x' in:
- /// \code
- /// struct S {
- /// static int x;
- /// };
- /// \endcode
- bool isStaticDataMember() const {
- return getDeclContext()->isRecord();
- }
-
- /// \brief Determine whether this is or was instantiated from an out-of-line
- /// definition of a static data member.
- bool isOutOfLine() const;
-
- /// \brief If this is a static data member, find its out-of-line definition.
- VarDecl *getOutOfLineDefinition();
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
@@ -728,35 +769,11 @@ public:
/// data member of a class template, set the template specialiation kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
-
- /// isFileVarDecl - Returns true for file scoped variable declaration.
- 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 (isStaticDataMember())
- return true;
-
- return false;
- }
-
- /// \brief Determine whether this is a tentative definition of a
- /// variable in C.
- bool isTentativeDefinition(ASTContext &Context) const;
-
- /// \brief Determines whether this variable is a variable with
- /// external, C linkage.
- bool isExternC() const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= VarFirst && D->getKind() <= VarLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const VarDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= VarFirst && K <= VarLast; }
};
class ImplicitParamDecl : public VarDecl {
@@ -770,7 +787,8 @@ public:
QualType T);
// Implement isa/cast/dyncast/etc.
static bool classof(const ImplicitParamDecl *D) { return true; }
- static bool classof(const Decl *D) { return D->getKind() == ImplicitParam; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == ImplicitParam; }
};
/// ParmVarDecl - Represent a parameter to a function.
@@ -876,10 +894,9 @@ public:
void setOwningFunction(DeclContext *FD) { setDeclContext(FD); }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return (D->getKind() == ParmVar);
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ParmVarDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ParmVar; }
};
/// FunctionDecl - An instance of this class is created to represent a
@@ -1096,8 +1113,6 @@ public:
unsigned getBuiltinID() const;
- unsigned getNumParmVarDeclsFromType() const;
-
// Iterator access to formal parameters.
unsigned param_size() const { return getNumParams(); }
typedef ParmVarDecl **param_iterator;
@@ -1110,7 +1125,7 @@ public:
param_const_iterator param_end() const { return ParamInfo+param_size(); }
/// getNumParams - Return the number of parameters this function must have
- /// based on its functiontype. This is the length of the PararmInfo array
+ /// based on its FunctionType. This is the length of the ParamInfo array
/// after it has been created.
unsigned getNumParams() const;
@@ -1122,7 +1137,7 @@ public:
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
}
- void setParams(ASTContext& C, ParmVarDecl **NewParamInfo, unsigned NumParams);
+ void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
/// getMinRequiredArguments - Returns the minimum number of arguments
/// needed to call this function. This may be fewer than the number of
@@ -1267,8 +1282,7 @@ public:
/// be inserted.
///
/// \param TSK the kind of template specialization this is.
- void setFunctionTemplateSpecialization(ASTContext &Context,
- FunctionTemplateDecl *Template,
+ void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
void *InsertPos,
TemplateSpecializationKind TSK = TSK_ImplicitInstantiation);
@@ -1295,10 +1309,11 @@ public:
bool isOutOfLine() const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FunctionDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= FunctionFirst && K <= FunctionLast;
+ }
static DeclContext *castToDeclContext(const FunctionDecl *D) {
return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
}
@@ -1347,11 +1362,20 @@ public:
Expr *getBitWidth() const { return BitWidth; }
void setBitWidth(Expr *BW) { BitWidth = BW; }
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= FieldFirst && D->getKind() <= FieldLast;
+ /// getParent - Returns the parent of this field declaration, which
+ /// is the struct in which this method is defined.
+ const RecordDecl *getParent() const {
+ return cast<RecordDecl>(getDeclContext());
}
+
+ RecordDecl *getParent() {
+ return cast<RecordDecl>(getDeclContext());
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FieldDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= FieldFirst && K <= FieldLast; }
};
/// EnumConstantDecl - An instance of this object exists for each enum constant
@@ -1385,8 +1409,9 @@ public:
void setInitVal(const llvm::APSInt &V) { Val = V; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == EnumConstant; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const EnumConstantDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == EnumConstant; }
friend class StmtIteratorBase;
};
@@ -1418,10 +1443,9 @@ public:
void setTypeForDecl(Type *TD) { TypeForDecl = TD; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= TypeFirst && D->getKind() <= TypeLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypeDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= TypeFirst && K <= TypeLast; }
};
@@ -1460,8 +1484,9 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == Typedef; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypedefDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Typedef; }
};
class TypedefDecl;
@@ -1486,6 +1511,11 @@ private:
/// it is a declaration ("struct foo;").
bool IsDefinition : 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,
+ bool IsEmbeddedInDeclarator : 1;
+
/// TypedefForAnonDecl - If a TagDecl is anonymous and part of a typedef,
/// this points to the TypedefDecl. Used for mangling.
TypedefDecl *TypedefForAnonDecl;
@@ -1502,6 +1532,7 @@ protected:
assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
TagDeclKind = TK;
IsDefinition = false;
+ IsEmbeddedInDeclarator = false;
setPreviousDeclaration(PrevDecl);
}
@@ -1535,6 +1566,13 @@ public:
return IsDefinition;
}
+ bool isEmbeddedInDeclarator() const {
+ return IsEmbeddedInDeclarator;
+ }
+ void setEmbeddedInDeclarator(bool isInDeclarator) {
+ IsEmbeddedInDeclarator = isInDeclarator;
+ }
+
/// \brief Whether this declaration declares a type that is
/// dependent, i.e., a type that somehow depends on template
/// parameters.
@@ -1557,7 +1595,9 @@ public:
/// specific TagDecl is defining declaration, not whether or not the
/// struct/union/class/enum type is defined. This method returns NULL if
/// there is no TagDecl that defines the struct/union/class/enum.
- TagDecl* getDefinition(ASTContext& C) const;
+ TagDecl* getDefinition() const;
+
+ void setDefinition(bool V) { IsDefinition = V; }
const char *getKindName() const {
return ElaboratedType::getNameForTagKind(getTagKind());
@@ -1583,10 +1623,9 @@ public:
void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefForAnonDecl = TDD; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= TagFirst && D->getKind() <= TagLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TagDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K >= TagFirst && K <= TagLast; }
static DeclContext *castToDeclContext(const TagDecl *D) {
return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
@@ -1594,8 +1633,6 @@ public:
static TagDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
}
-
- void setDefinition(bool V) { IsDefinition = V; }
};
/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
@@ -1641,7 +1678,7 @@ public:
/// declaration as being defined; it's enumerators have already been
/// added (via DeclContext::addDecl). NewType is the new underlying
/// type of the enumeration type.
- void completeDefinition(ASTContext &C, QualType NewType,
+ void completeDefinition(QualType NewType,
QualType PromotionType);
// enumerator_iterator - Iterates through the enumerators of this
@@ -1679,8 +1716,9 @@ public:
void setInstantiationOfMemberEnum(EnumDecl *IF) { InstantiatedFrom = IF; }
- static bool classof(const Decl *D) { return D->getKind() == Enum; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const EnumDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Enum; }
};
@@ -1763,8 +1801,8 @@ public:
/// RecordDecl is defining declaration, not whether or not the record
/// type is defined. This method returns NULL if there is no RecordDecl
/// that defines the struct/union/tag.
- RecordDecl* getDefinition(ASTContext& C) const {
- return cast_or_null<RecordDecl>(TagDecl::getDefinition(C));
+ RecordDecl* getDefinition() const {
+ return cast_or_null<RecordDecl>(TagDecl::getDefinition());
}
// Iterator access to field members. The field iterator only visits
@@ -1787,12 +1825,13 @@ public:
/// completeDefinition - Notes that the definition of this type is
/// now complete.
- void completeDefinition(ASTContext& C);
+ void completeDefinition();
- static bool classof(const Decl *D) {
- return D->getKind() >= RecordFirst && D->getKind() <= RecordLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const RecordDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= RecordFirst && K <= RecordLast;
+ }
};
class FileScopeAsmDecl : public Decl {
@@ -1807,10 +1846,9 @@ public:
StringLiteral *getAsmString() { return AsmString; }
void setAsmString(StringLiteral *Asm) { AsmString = Asm; }
- static bool classof(const Decl *D) {
- return D->getKind() == FileScopeAsm;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FileScopeAsmDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == FileScopeAsm; }
};
/// BlockDecl - This represents a block literal declaration, which is like an
@@ -1869,11 +1907,12 @@ public:
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
}
- void setParams(ASTContext& C, ParmVarDecl **NewParamInfo, unsigned NumParams);
+ void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == Block; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const BlockDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Block; }
static DeclContext *castToDeclContext(const BlockDecl *D) {
return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
}
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 775bce2a15fc..a407a1627747 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -480,6 +480,7 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *) { return true; }
+ static bool classofKind(Kind K) { return true; }
static DeclContext *castToDeclContext(const Decl *);
static Decl *castFromDeclContext(const DeclContext *);
@@ -1020,17 +1021,43 @@ 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>
+struct cast_convert_decl_context {
+ static const ToTy *doit(const DeclContext *Val) {
+ return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
+ }
+
+ static ToTy *doit(DeclContext *Val) {
+ return static_cast<ToTy*>(Decl::castFromDeclContext(Val));
+ }
+};
+
+// Specialization selected when ToTy is a known subclass of DeclContext.
+template <class ToTy>
+struct cast_convert_decl_context<ToTy, true> {
+ static const ToTy *doit(const DeclContext *Val) {
+ return static_cast<const ToTy*>(Val);
+ }
+
+ static ToTy *doit(DeclContext *Val) {
+ return static_cast<ToTy*>(Val);
+ }
+};
+
+
} // end clang.
namespace llvm {
-/// Implement a isa_impl_wrap specialization to check whether a DeclContext is
-/// a specific Decl.
+/// isa<T>(DeclContext*)
template<class ToTy>
struct isa_impl_wrap<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {
static bool doit(const ::clang::DeclContext &Val) {
- return ToTy::classof(::clang::Decl::castFromDeclContext(&Val));
+ return ToTy::classofKind(Val.getDeclKind());
}
};
template<class ToTy>
@@ -1038,6 +1065,34 @@ struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
: public isa_impl_wrap<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {};
+/// cast<T>(DeclContext*)
+template<class ToTy>
+struct cast_convert_val<ToTy,
+ const ::clang::DeclContext,const ::clang::DeclContext> {
+ static const ToTy &doit(const ::clang::DeclContext &Val) {
+ return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
+ }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
+ static ToTy &doit(::clang::DeclContext &Val) {
+ return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
+ }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy,
+ const ::clang::DeclContext*, const ::clang::DeclContext*> {
+ static const ToTy *doit(const ::clang::DeclContext *Val) {
+ return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
+ }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
+ static ToTy *doit(::clang::DeclContext *Val) {
+ return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
+ }
+};
+
/// Implement cast_convert_val for Decl -> DeclContext conversions.
template<class FromTy>
struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
@@ -1067,31 +1122,6 @@ struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
}
};
-/// Implement cast_convert_val for DeclContext -> Decl conversions.
-template<class ToTy>
-struct cast_convert_val<ToTy,
- const ::clang::DeclContext,const ::clang::DeclContext> {
- static ToTy &doit(const ::clang::DeclContext &Val) {
- return *reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(&Val));
- }
-};
-template<class ToTy>
-struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext>
- : public cast_convert_val<ToTy,
- const ::clang::DeclContext,const ::clang::DeclContext> {};
-
-template<class ToTy>
-struct cast_convert_val<ToTy,
- const ::clang::DeclContext*, const ::clang::DeclContext*> {
- static ToTy *doit(const ::clang::DeclContext *Val) {
- return reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(Val));
- }
-};
-template<class ToTy>
-struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*>
- : public cast_convert_val<ToTy,
- const ::clang::DeclContext*,const ::clang::DeclContext*> {};
-
} // end namespace llvm
#endif
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 73ebf52d383b..0978c6da9d66 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -145,6 +145,10 @@ public:
/// class (or not).
bool isVirtual() const { return Virtual; }
+ /// \brief Determine whether this base class if a base of a class declared
+ /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
+ bool isBaseOfClass() const { return BaseOfClass; }
+
/// getAccessSpecifier - Returns the access specifier for this base
/// specifier. This is the actual base specifier as used for
/// semantic analysis, so the result can never be AS_none. To
@@ -174,115 +178,137 @@ public:
/// FIXME: This class will disappear once we've properly taught RecordDecl
/// to deal with C++-specific things.
class CXXRecordDecl : public RecordDecl {
- /// UserDeclaredConstructor - True when this class has a
- /// user-declared constructor.
- bool UserDeclaredConstructor : 1;
- /// UserDeclaredCopyConstructor - True when this class has a
- /// user-declared copy constructor.
- bool UserDeclaredCopyConstructor : 1;
+ friend void TagDecl::startDefinition();
- /// UserDeclaredCopyAssignment - True when this class has a
- /// user-declared copy assignment operator.
- bool UserDeclaredCopyAssignment : 1;
+ struct DefinitionData {
+ DefinitionData(CXXRecordDecl *D);
- /// UserDeclaredDestructor - True when this class has a
- /// user-declared destructor.
- bool UserDeclaredDestructor : 1;
+ /// UserDeclaredConstructor - True when this class has a
+ /// user-declared constructor.
+ bool UserDeclaredConstructor : 1;
- /// Aggregate - True when this class is an aggregate.
- bool Aggregate : 1;
+ /// UserDeclaredCopyConstructor - True when this class has a
+ /// user-declared copy constructor.
+ bool UserDeclaredCopyConstructor : 1;
- /// PlainOldData - True when this class is a POD-type.
- bool PlainOldData : 1;
+ /// UserDeclaredCopyAssignment - True when this class has a
+ /// user-declared copy assignment operator.
+ bool UserDeclaredCopyAssignment : 1;
- /// Empty - true when this class is empty for traits purposes, i.e. has no
- /// data members other than 0-width bit-fields, has no virtual function/base,
- /// and doesn't inherit from a non-empty class. Doesn't take union-ness into
- /// account.
- bool Empty : 1;
+ /// UserDeclaredDestructor - True when this class has a
+ /// user-declared destructor.
+ bool UserDeclaredDestructor : 1;
- /// Polymorphic - True when this class is polymorphic, i.e. has at least one
- /// virtual member or derives from a polymorphic class.
- bool Polymorphic : 1;
+ /// Aggregate - True when this class is an aggregate.
+ bool Aggregate : 1;
- /// Abstract - True when this class is abstract, i.e. has at least one
- /// pure virtual function, (that can come from a base class).
- bool Abstract : 1;
+ /// PlainOldData - True when this class is a POD-type.
+ bool PlainOldData : 1;
- /// HasTrivialConstructor - True when this class has a trivial constructor.
- ///
- /// C++ [class.ctor]p5. A constructor is trivial if it is an
- /// implicitly-declared default constructor and if:
- /// * its class has no virtual functions and no virtual base classes, and
- /// * all the direct base classes of its class have trivial constructors, and
- /// * for all the nonstatic data members of its class that are of class type
- /// (or array thereof), each such class has a trivial constructor.
- bool HasTrivialConstructor : 1;
+ /// Empty - true when this class is empty for traits purposes,
+ /// i.e. has no data members other than 0-width bit-fields, has no
+ /// virtual function/base, and doesn't inherit from a non-empty
+ /// class. Doesn't take union-ness into account.
+ bool Empty : 1;
- /// HasTrivialCopyConstructor - True when this class has a trivial copy
- /// constructor.
- ///
- /// C++ [class.copy]p6. A copy constructor for class X is trivial
- /// if it is implicitly declared and if
- /// * class X has no virtual functions and no virtual base classes, and
- /// * each direct base class of X has a trivial copy constructor, and
- /// * for all the nonstatic data members of X that are of class type (or
- /// array thereof), each such class type has a trivial copy constructor;
- /// otherwise the copy constructor is non-trivial.
- bool HasTrivialCopyConstructor : 1;
+ /// Polymorphic - True when this class is polymorphic, i.e. has at
+ /// least one virtual member or derives from a polymorphic class.
+ bool Polymorphic : 1;
- /// HasTrivialCopyAssignment - True when this class has a trivial copy
- /// assignment operator.
- ///
- /// C++ [class.copy]p11. A copy assignment operator for class X is
- /// trivial if it is implicitly declared and if
- /// * class X has no virtual functions and no virtual base classes, and
- /// * each direct base class of X has a trivial copy assignment operator, and
- /// * for all the nonstatic data members of X that are of class type (or
- /// array thereof), each such class type has a trivial copy assignment
- /// operator;
- /// otherwise the copy assignment operator is non-trivial.
- bool HasTrivialCopyAssignment : 1;
+ /// Abstract - True when this class is abstract, i.e. has at least
+ /// one pure virtual function, (that can come from a base class).
+ bool Abstract : 1;
- /// HasTrivialDestructor - True when this class has a trivial destructor.
- ///
- /// C++ [class.dtor]p3. A destructor is trivial if it is an
- /// implicitly-declared destructor and if:
- /// * all of the direct base classes of its class have trivial destructors
- /// and
- /// * for all of the non-static data members of its class that are of class
- /// type (or array thereof), each such class has a trivial destructor.
- bool HasTrivialDestructor : 1;
+ /// HasTrivialConstructor - True when this class has a trivial constructor.
+ ///
+ /// C++ [class.ctor]p5. A constructor is trivial if it is an
+ /// implicitly-declared default constructor and if:
+ /// * its class has no virtual functions and no virtual base classes, and
+ /// * all the direct base classes of its class have trivial constructors, and
+ /// * for all the nonstatic data members of its class that are of class type
+ /// (or array thereof), each such class has a trivial constructor.
+ bool HasTrivialConstructor : 1;
+
+ /// HasTrivialCopyConstructor - True when this class has a trivial copy
+ /// constructor.
+ ///
+ /// C++ [class.copy]p6. A copy constructor for class X is trivial
+ /// if it is implicitly declared and if
+ /// * class X has no virtual functions and no virtual base classes, and
+ /// * each direct base class of X has a trivial copy constructor, and
+ /// * for all the nonstatic data members of X that are of class type (or
+ /// array thereof), each such class type has a trivial copy constructor;
+ /// otherwise the copy constructor is non-trivial.
+ bool HasTrivialCopyConstructor : 1;
+
+ /// HasTrivialCopyAssignment - True when this class has a trivial copy
+ /// assignment operator.
+ ///
+ /// C++ [class.copy]p11. A copy assignment operator for class X is
+ /// trivial if it is implicitly declared and if
+ /// * class X has no virtual functions and no virtual base classes, and
+ /// * each direct base class of X has a trivial copy assignment operator, and
+ /// * for all the nonstatic data members of X that are of class type (or
+ /// array thereof), each such class type has a trivial copy assignment
+ /// operator;
+ /// otherwise the copy assignment operator is non-trivial.
+ bool HasTrivialCopyAssignment : 1;
- /// ComputedVisibleConversions - True when visible conversion functions are
- /// already computed and are available.
- bool ComputedVisibleConversions : 1;
+ /// HasTrivialDestructor - True when this class has a trivial destructor.
+ ///
+ /// C++ [class.dtor]p3. A destructor is trivial if it is an
+ /// implicitly-declared destructor and if:
+ /// * all of the direct base classes of its class have trivial destructors
+ /// and
+ /// * for all of the non-static data members of its class that are of class
+ /// type (or array thereof), each such class has a trivial destructor.
+ bool HasTrivialDestructor : 1;
+
+ /// ComputedVisibleConversions - True when visible conversion functions are
+ /// already computed and are available.
+ bool ComputedVisibleConversions : 1;
- /// Bases - Base classes of this class.
- /// FIXME: This is wasted space for a union.
- CXXBaseSpecifier *Bases;
+ /// Bases - Base classes of this class.
+ /// FIXME: This is wasted space for a union.
+ CXXBaseSpecifier *Bases;
+
+ /// NumBases - The number of base class specifiers in Bases.
+ unsigned NumBases;
+
+ /// VBases - direct and indirect virtual base classes of this class.
+ CXXBaseSpecifier *VBases;
+
+ /// NumVBases - The number of virtual base class specifiers in VBases.
+ unsigned NumVBases;
- /// NumBases - The number of base class specifiers in Bases.
- unsigned NumBases;
+ /// Conversions - Overload set containing the conversion functions
+ /// of this C++ class (but not its inherited conversion
+ /// functions). Each of the entries in this overload set is a
+ /// CXXConversionDecl.
+ UnresolvedSet<4> Conversions;
- /// VBases - direct and indirect virtual base classes of this class.
- CXXBaseSpecifier *VBases;
+ /// VisibleConversions - Overload set containing the conversion
+ /// functions of this C++ class and all those inherited conversion
+ /// functions that are visible in this class. Each of the entries
+ /// in this overload set is a CXXConversionDecl or a
+ /// FunctionTemplateDecl.
+ UnresolvedSet<4> VisibleConversions;
- /// NumVBases - The number of virtual base class specifiers in VBases.
- unsigned NumVBases;
+ /// Definition - The declaration which defines this record.
+ CXXRecordDecl *Definition;
- /// Conversions - Overload set containing the conversion functions
- /// of this C++ class (but not its inherited conversion
- /// functions). Each of the entries in this overload set is a
- /// CXXConversionDecl.
- UnresolvedSet<4> Conversions;
+ } *DefinitionData;
- /// VisibleConversions - Overload set containing the conversion functions
- /// of this C++ class and all those inherited conversion functions that
- /// are visible in this class. Each of the entries in this overload set is
- /// a CXXConversionDecl or a FunctionTemplateDecl.
- UnresolvedSet<4> VisibleConversions;
+ struct DefinitionData &data() {
+ assert(DefinitionData && "queried property of class with no definition");
+ return *DefinitionData;
+ }
+
+ const struct DefinitionData &data() const {
+ assert(DefinitionData && "queried property of class with no definition");
+ return *DefinitionData;
+ }
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
@@ -336,6 +362,13 @@ public:
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
+ CXXRecordDecl *getDefinition() const {
+ if (!DefinitionData) return 0;
+ return data().Definition;
+ }
+
+ bool hasDefinition() const { return DefinitionData != 0; }
+
static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL = SourceLocation(),
@@ -345,21 +378,22 @@ public:
virtual void Destroy(ASTContext& C);
bool isDynamicClass() const {
- return Polymorphic || NumVBases != 0;
+ return data().Polymorphic || data().NumVBases != 0;
}
/// setBases - Sets the base classes of this struct or class.
- void setBases(ASTContext &C,
- CXXBaseSpecifier const * const *Bases, unsigned NumBases);
+ void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
/// getNumBases - Retrieves the number of base classes of this
/// class.
- unsigned getNumBases() const { return NumBases; }
+ unsigned getNumBases() const { return data().NumBases; }
- base_class_iterator bases_begin() { return Bases; }
- base_class_const_iterator bases_begin() const { return Bases; }
- base_class_iterator bases_end() { return Bases + NumBases; }
- base_class_const_iterator bases_end() const { return Bases + NumBases; }
+ base_class_iterator bases_begin() { return data().Bases; }
+ base_class_const_iterator bases_begin() const { return data().Bases; }
+ base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
+ base_class_const_iterator bases_end() const {
+ return bases_begin() + data().NumBases;
+ }
reverse_base_class_iterator bases_rbegin() {
return reverse_base_class_iterator(bases_end());
}
@@ -375,12 +409,14 @@ public:
/// getNumVBases - Retrieves the number of virtual base classes of this
/// class.
- unsigned getNumVBases() const { return NumVBases; }
+ unsigned getNumVBases() const { return data().NumVBases; }
- base_class_iterator vbases_begin() { return VBases; }
- base_class_const_iterator vbases_begin() const { return VBases; }
- base_class_iterator vbases_end() { return VBases + NumVBases; }
- base_class_const_iterator vbases_end() const { return VBases + NumVBases; }
+ base_class_iterator vbases_begin() { return data().VBases; }
+ base_class_const_iterator vbases_begin() const { return data().VBases; }
+ base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
+ base_class_const_iterator vbases_end() const {
+ return vbases_begin() + data().NumVBases;
+ }
reverse_base_class_iterator vbases_rbegin() {
return reverse_base_class_iterator(vbases_end());
}
@@ -445,17 +481,14 @@ public:
/// user-declared constructors. When true, a default constructor
/// will not be implicitly declared.
bool hasUserDeclaredConstructor() const {
- assert((isDefinition() ||
- cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
- "Incomplete record decl!");
- return UserDeclaredConstructor;
+ return data().UserDeclaredConstructor;
}
/// hasUserDeclaredCopyConstructor - Whether this class has a
/// user-declared copy constructor. When false, a copy constructor
/// will be implicitly declared.
bool hasUserDeclaredCopyConstructor() const {
- return UserDeclaredCopyConstructor;
+ return data().UserDeclaredCopyConstructor;
}
/// addedAssignmentOperator - Notify the class that another assignment
@@ -467,45 +500,45 @@ public:
/// user-declared copy assignment operator. When false, a copy
/// assigment operator will be implicitly declared.
bool hasUserDeclaredCopyAssignment() const {
- return UserDeclaredCopyAssignment;
+ return data().UserDeclaredCopyAssignment;
}
/// hasUserDeclaredDestructor - Whether this class has a
/// user-declared destructor. When false, a destructor will be
/// implicitly declared.
- bool hasUserDeclaredDestructor() const { return UserDeclaredDestructor; }
+ bool hasUserDeclaredDestructor() const {
+ return data().UserDeclaredDestructor;
+ }
/// setUserDeclaredDestructor - Set whether this class has a
/// user-declared destructor. If not set by the time the class is
/// fully defined, a destructor will be implicitly declared.
void setUserDeclaredDestructor(bool UCD) {
- UserDeclaredDestructor = UCD;
+ data().UserDeclaredDestructor = UCD;
}
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
UnresolvedSetImpl *getConversionFunctions() {
- assert((this->isDefinition() ||
- cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
- "getConversionFunctions() called on incomplete type");
- return &Conversions;
+ return &data().Conversions;
}
const UnresolvedSetImpl *getConversionFunctions() const {
- assert((this->isDefinition() ||
- cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
- "getConversionFunctions() called on incomplete type");
- return &Conversions;
+ return &data().Conversions;
}
typedef UnresolvedSetImpl::iterator conversion_iterator;
- conversion_iterator conversion_begin() const { return Conversions.begin(); }
- conversion_iterator conversion_end() const { return Conversions.end(); }
+ conversion_iterator conversion_begin() const {
+ return getConversionFunctions()->begin();
+ }
+ conversion_iterator conversion_end() const {
+ return getConversionFunctions()->end();
+ }
/// Replaces a conversion function with a new declaration.
///
/// Returns true if the old conversion was found.
bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
- return Conversions.replace(Old, New);
+ return getConversionFunctions()->replace(Old, New);
}
/// getVisibleConversionFunctions - get all conversion functions visible
@@ -532,11 +565,11 @@ public:
/// [dcl.init.aggr]), which is a class with no user-declared
/// constructors, no private or protected non-static data members,
/// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
- bool isAggregate() const { return Aggregate; }
+ bool isAggregate() const { return data().Aggregate; }
/// setAggregate - Set whether this class is an aggregate (C++
/// [dcl.init.aggr]).
- void setAggregate(bool Agg) { Aggregate = Agg; }
+ void setAggregate(bool Agg) { data().Aggregate = Agg; }
/// setMethodAsVirtual - Make input method virtual and set the necesssary
/// special function bits and other bits accordingly.
@@ -546,66 +579,74 @@ public:
/// that is an aggregate that has no non-static non-POD data members, no
/// reference data members, no user-defined copy assignment operator and no
/// user-defined destructor.
- bool isPOD() const { return PlainOldData; }
+ bool isPOD() const { return data().PlainOldData; }
/// setPOD - Set whether this class is a POD-type (C++ [class]p4).
- void setPOD(bool POD) { PlainOldData = POD; }
+ void setPOD(bool POD) { data().PlainOldData = POD; }
/// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which
/// means it has a virtual function, virtual base, data member (other than
/// 0-width bit-field) or inherits from a non-empty class. Does NOT include
/// a check for union-ness.
- bool isEmpty() const { return Empty; }
+ bool isEmpty() const { return data().Empty; }
/// Set whether this class is empty (C++0x [meta.unary.prop])
- void setEmpty(bool Emp) { Empty = Emp; }
+ void setEmpty(bool Emp) { data().Empty = Emp; }
/// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]),
/// which means that the class contains or inherits a virtual function.
- bool isPolymorphic() const { return Polymorphic; }
+ bool isPolymorphic() const { return data().Polymorphic; }
/// setPolymorphic - Set whether this class is polymorphic (C++
/// [class.virtual]).
- void setPolymorphic(bool Poly) { Polymorphic = Poly; }
+ void setPolymorphic(bool Poly) { data().Polymorphic = Poly; }
/// isAbstract - Whether this class is abstract (C++ [class.abstract]),
/// which means that the class contains or inherits a pure virtual function.
- bool isAbstract() const { return Abstract; }
+ bool isAbstract() const { return data().Abstract; }
/// setAbstract - Set whether this class is abstract (C++ [class.abstract])
- void setAbstract(bool Abs) { Abstract = Abs; }
+ void setAbstract(bool Abs) { data().Abstract = Abs; }
// hasTrivialConstructor - Whether this class has a trivial constructor
// (C++ [class.ctor]p5)
- bool hasTrivialConstructor() const { return HasTrivialConstructor; }
+ bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
// setHasTrivialConstructor - Set whether this class has a trivial constructor
// (C++ [class.ctor]p5)
- void setHasTrivialConstructor(bool TC) { HasTrivialConstructor = TC; }
+ void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; }
// hasTrivialCopyConstructor - Whether this class has a trivial copy
// constructor (C++ [class.copy]p6)
- bool hasTrivialCopyConstructor() const { return HasTrivialCopyConstructor; }
+ bool hasTrivialCopyConstructor() const {
+ return data().HasTrivialCopyConstructor;
+ }
// setHasTrivialCopyConstructor - Set whether this class has a trivial
// copy constructor (C++ [class.copy]p6)
- void setHasTrivialCopyConstructor(bool TC) { HasTrivialCopyConstructor = TC; }
+ void setHasTrivialCopyConstructor(bool TC) {
+ data().HasTrivialCopyConstructor = TC;
+ }
// hasTrivialCopyAssignment - Whether this class has a trivial copy
// assignment operator (C++ [class.copy]p11)
- bool hasTrivialCopyAssignment() const { return HasTrivialCopyAssignment; }
+ bool hasTrivialCopyAssignment() const {
+ return data().HasTrivialCopyAssignment;
+ }
// setHasTrivialCopyAssignment - Set whether this class has a
// trivial copy assignment operator (C++ [class.copy]p11)
- void setHasTrivialCopyAssignment(bool TC) { HasTrivialCopyAssignment = TC; }
+ void setHasTrivialCopyAssignment(bool TC) {
+ data().HasTrivialCopyAssignment = TC;
+ }
// hasTrivialDestructor - Whether this class has a trivial destructor
// (C++ [class.dtor]p3)
- bool hasTrivialDestructor() const { return HasTrivialDestructor; }
+ bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
// setHasTrivialDestructor - Set whether this class has a trivial destructor
// (C++ [class.dtor]p3)
- void setHasTrivialDestructor(bool TC) { HasTrivialDestructor = TC; }
+ void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; }
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
@@ -826,10 +867,11 @@ public:
return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
}
- static bool classof(const Decl *D) {
- return D->getKind() == CXXRecord ||
- D->getKind() == ClassTemplateSpecialization ||
- D->getKind() == ClassTemplatePartialSpecialization;
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K == CXXRecord ||
+ K == ClassTemplateSpecialization ||
+ K == ClassTemplatePartialSpecialization;
}
static bool classof(const CXXRecordDecl *D) { return true; }
static bool classof(const ClassTemplateSpecializationDecl *D) {
@@ -911,10 +953,11 @@ public:
bool hasInlineBody() const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= CXXMethod && D->getKind() <= CXXConversion;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXMethodDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= CXXMethod && K <= CXXConversion;
+ }
};
/// CXXBaseOrMemberInitializer - Represents a C++ base or member
@@ -939,9 +982,9 @@ class CXXBaseOrMemberInitializer {
/// \brief The source location for the field name.
SourceLocation MemberLocation;
- /// Args - The arguments used to initialize the base or member.
- Stmt **Args;
- unsigned NumArgs;
+ /// \brief The argument used to initialize the base or member, which may
+ /// end up constructing an object (when multiple arguments are involved).
+ Stmt *Init;
/// \brief Stores either the constructor to call to initialize this base or
/// member (a CXXConstructorDecl pointer), or stores the anonymous union of
@@ -961,7 +1004,7 @@ class CXXBaseOrMemberInitializer {
/// @endcode
/// In above example, BaseOrMember holds the field decl. for anonymous union
/// and AnonUnionMember holds field decl for au_i1.
- llvm::PointerUnion<CXXConstructorDecl *, FieldDecl *> CtorOrAnonUnion;
+ FieldDecl *AnonUnionMember;
/// LParenLoc - Location of the left paren of the ctor-initializer.
SourceLocation LParenLoc;
@@ -973,30 +1016,22 @@ public:
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
explicit
CXXBaseOrMemberInitializer(ASTContext &Context,
- TypeSourceInfo *TInfo, CXXConstructorDecl *C,
+ TypeSourceInfo *TInfo,
SourceLocation L,
- Expr **Args, unsigned NumArgs,
+ Expr *Init,
SourceLocation R);
/// CXXBaseOrMemberInitializer - Creates a new member initializer.
explicit
CXXBaseOrMemberInitializer(ASTContext &Context,
FieldDecl *Member, SourceLocation MemberLoc,
- CXXConstructorDecl *C, SourceLocation L,
- Expr **Args, unsigned NumArgs,
+ SourceLocation L,
+ Expr *Init,
SourceLocation R);
/// \brief Destroy the base or member initializer.
void Destroy(ASTContext &Context);
- /// arg_iterator - Iterates through the member initialization
- /// arguments.
- typedef ExprIterator arg_iterator;
-
- /// arg_const_iterator - Iterates through the member initialization
- /// arguments.
- typedef ConstExprIterator const_arg_iterator;
-
/// isBaseInitializer - Returns true when this initializer is
/// initializing a base class.
bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); }
@@ -1046,32 +1081,16 @@ public:
SourceRange getSourceRange() const;
FieldDecl *getAnonUnionMember() const {
- return CtorOrAnonUnion.dyn_cast<FieldDecl *>();
+ return AnonUnionMember;
}
void setAnonUnionMember(FieldDecl *anonMember) {
- CtorOrAnonUnion = anonMember;
- }
-
- const CXXConstructorDecl *getConstructor() const {
- return CtorOrAnonUnion.dyn_cast<CXXConstructorDecl *>();
+ AnonUnionMember = anonMember;
}
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
- /// arg_begin() - Retrieve an iterator to the first initializer argument.
- arg_iterator arg_begin() { return Args; }
- /// arg_begin() - Retrieve an iterator to the first initializer argument.
- const_arg_iterator const_arg_begin() const { return Args; }
-
- /// arg_end() - Retrieve an iterator past the last initializer argument.
- arg_iterator arg_end() { return Args + NumArgs; }
- /// arg_end() - Retrieve an iterator past the last initializer argument.
- const_arg_iterator const_arg_end() const { return Args + NumArgs; }
-
- /// getNumArgs - Determine the number of arguments used to
- /// initialize the member or base.
- unsigned getNumArgs() const { return NumArgs; }
+ Expr *getInit() { return static_cast<Expr *>(Init); }
};
/// CXXConstructorDecl - Represents a C++ constructor within a
@@ -1084,8 +1103,9 @@ public:
/// };
/// @endcode
class CXXConstructorDecl : public CXXMethodDecl {
- /// Explicit - Whether this constructor is explicit.
- bool Explicit : 1;
+ /// IsExplicitSpecified - Whether this constructor declaration has the
+ /// 'explicit' keyword specified.
+ bool IsExplicitSpecified : 1;
/// ImplicitlyDefined - Whether this constructor was implicitly
/// defined by the compiler. When false, the constructor was defined
@@ -1103,9 +1123,10 @@ class CXXConstructorDecl : public CXXMethodDecl {
CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- bool isExplicit, bool isInline, bool isImplicitlyDeclared)
+ bool isExplicitSpecified, bool isInline,
+ bool isImplicitlyDeclared)
: CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false, isInline),
- Explicit(isExplicit), ImplicitlyDefined(false),
+ IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -1118,8 +1139,15 @@ public:
bool isExplicit,
bool isInline, bool isImplicitlyDeclared);
+ /// isExplicitSpecified - Whether this constructor declaration has the
+ /// 'explicit' keyword specified.
+ bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
/// isExplicit - Whether this constructor was marked "explicit" or not.
- bool isExplicit() const { return Explicit; }
+ bool isExplicit() const {
+ return cast<CXXConstructorDecl>(getFirstDeclaration())
+ ->isExplicitSpecified();
+ }
/// isImplicitlyDefined - Whether this constructor was implicitly
/// defined. If false, then this constructor was defined by the
@@ -1212,10 +1240,9 @@ public:
bool isCopyConstructorLikeSpecialization() const;
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == CXXConstructor;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConstructorDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == CXXConstructor; }
};
/// CXXDestructorDecl - Represents a C++ destructor within a
@@ -1274,10 +1301,9 @@ public:
const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == CXXDestructor;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXDestructorDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == CXXDestructor; }
};
/// CXXConversionDecl - Represents a C++ conversion function within a
@@ -1290,16 +1316,16 @@ public:
/// };
/// @endcode
class CXXConversionDecl : public CXXMethodDecl {
- /// Explicit - Whether this conversion function is marked
- /// "explicit", meaning that it can only be applied when the user
+ /// IsExplicitSpecified - Whether this conversion function declaration is
+ /// marked "explicit", meaning that it can only be applied when the user
/// explicitly wrote a cast. This is a C++0x feature.
- bool Explicit : 1;
+ bool IsExplicitSpecified : 1;
CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isExplicit)
+ bool isInline, bool isExplicitSpecified)
: CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false, isInline),
- Explicit(isExplicit) { }
+ IsExplicitSpecified(isExplicitSpecified) { }
public:
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
@@ -1307,10 +1333,18 @@ public:
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicit);
+ /// IsExplicitSpecified - Whether this conversion function declaration is
+ /// marked "explicit", meaning that it can only be applied when the user
+ /// explicitly wrote a cast. This is a C++0x feature.
+ bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
/// isExplicit - Whether this is an explicit conversion operator
/// (C++0x only). Explicit conversion operators are only considered
/// when the user has explicitly written a cast.
- bool isExplicit() const { return Explicit; }
+ bool isExplicit() const {
+ return cast<CXXConversionDecl>(getFirstDeclaration())
+ ->isExplicitSpecified();
+ }
/// getConversionType - Returns the type that this conversion
/// function is converting to.
@@ -1319,10 +1353,9 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == CXXConversion;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConversionDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == CXXConversion; }
};
/// FriendDecl - Represents the declaration of a friend entity,
@@ -1391,10 +1424,9 @@ public:
void setSpecialization(bool WS) { WasSpecialization = WS; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::Friend;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FriendDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::Friend; }
};
/// LinkageSpecDecl - This represents a linkage specification. For example:
@@ -1432,10 +1464,9 @@ public:
/// braces in its syntactic form.
bool hasBraces() const { return HadBraces; }
- static bool classof(const Decl *D) {
- return D->getKind() == LinkageSpec;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const LinkageSpecDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == LinkageSpec; }
static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
}
@@ -1537,10 +1568,9 @@ public:
NamedDecl *Nominated,
DeclContext *CommonAncestor);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::UsingDirective;
- }
+ 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 == Decl::UsingDirective; }
// Friend for getUsingDirectiveName.
friend class DeclContext;
@@ -1598,6 +1628,16 @@ public:
return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
}
+ /// Returns the location of the alias name, i.e. 'foo' in
+ /// "namespace foo = ns::bar;".
+ SourceLocation getAliasLoc() const { return AliasLoc; }
+
+ /// Returns the location of the 'namespace' keyword.
+ SourceLocation getNamespaceLoc() const { return getLocation(); }
+
+ /// Returns the location of the identifier in the named namespace.
+ SourceLocation getTargetNameLoc() const { return IdentLoc; }
+
/// \brief Retrieve the namespace that this alias refers to, which
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *getAliasedNamespace() const { return Namespace; }
@@ -1610,10 +1650,9 @@ public:
SourceLocation IdentLoc,
NamedDecl *Namespace);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::NamespaceAlias;
- }
+ 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 == Decl::NamespaceAlias; }
};
/// UsingShadowDecl - Represents a shadow declaration introduced into
@@ -1660,10 +1699,9 @@ public:
return Using;
}
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::UsingShadow;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingShadowDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
};
/// UsingDecl - Represents a C++ using-declaration. For example:
@@ -1732,10 +1770,9 @@ public:
SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::Using;
- }
+ 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 == Decl::Using; }
};
/// UnresolvedUsingValueDecl - Represents a dependent using
@@ -1784,10 +1821,9 @@ public:
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
SourceLocation TargetNameLoc, DeclarationName TargetName);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::UnresolvedUsingValue;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingValue; }
};
/// UnresolvedUsingTypenameDecl - Represents a dependent using
@@ -1843,10 +1879,9 @@ public:
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
SourceLocation TargetNameLoc, DeclarationName TargetName);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::UnresolvedUsingTypename;
- }
+ 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 == Decl::UnresolvedUsingTypename; }
};
/// StaticAssertDecl - Represents a C++0x static_assert declaration.
@@ -1872,10 +1907,9 @@ public:
virtual ~StaticAssertDecl();
virtual void Destroy(ASTContext& C);
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::StaticAssert;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(StaticAssertDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == Decl::StaticAssert; }
};
/// Insertion operator for diagnostics. This allows sending AccessSpecifier's
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 0fb0db13bb57..e562d352e070 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -193,6 +193,9 @@ public:
ImplementationControl impControl = None);
virtual ObjCMethodDecl *getCanonicalDecl();
+ const ObjCMethodDecl *getCanonicalDecl() const {
+ return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
+ }
ObjCDeclQualifier getObjCDeclQualifier() const {
return ObjCDeclQualifier(objcDeclQualifier);
@@ -277,8 +280,9 @@ public:
bool isThisDeclarationADefinition() const { return Body; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCMethodDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCMethod; }
static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
}
@@ -383,11 +387,12 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= ObjCContainerFirst &&
- D->getKind() <= ObjCContainerLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCContainerDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= ObjCContainerFirst &&
+ K <= ObjCContainerLast;
+ }
static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
@@ -584,8 +589,9 @@ public:
Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(Type *TD) const { TypeForDecl = TD; }
- static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; }
+ 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; }
};
/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
@@ -630,8 +636,9 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; }
+ 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:
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
unsigned DeclAccess : 3;
@@ -657,8 +664,9 @@ public:
virtual void Destroy(ASTContext& C);
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
};
/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
@@ -749,8 +757,9 @@ public:
SourceLocation getLocEnd() const { return EndLoc; }
void setLocEnd(SourceLocation LE) { EndLoc = LE; }
- static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCProtocolDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCProtocol; }
};
/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
@@ -796,8 +805,9 @@ public:
void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
const SourceLocation *Locs, unsigned Num);
- static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCClassDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCClass; }
};
/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
@@ -846,10 +856,9 @@ public:
const SourceLocation *Locs, ASTContext &C) {
ReferencedProtocols.set(List, Num, Locs, C);
}
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCForwardProtocol;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCForwardProtocol; }
};
/// ObjCCategoryDecl - Represents a category declaration. A category allows
@@ -940,6 +949,8 @@ public:
ClassInterface->setCategoryList(this);
}
+ bool IsClassExtension() const { return getIdentifier() == 0; }
+
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation At) { AtLoc = At; }
@@ -950,8 +961,9 @@ public:
return SourceRange(AtLoc, getAtEndRange().getEnd());
}
- static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCCategoryDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCCategory; }
};
class ObjCImplDecl : public ObjCContainerDecl {
@@ -997,10 +1009,11 @@ public:
return propimpl_iterator(decls_end());
}
- static bool classof(const Decl *D) {
- return D->getKind() >= ObjCImplFirst && D->getKind() <= ObjCImplLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCImplDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= ObjCImplFirst && K <= ObjCImplLast;
+ }
};
/// ObjCCategoryImplDecl - An object of this class encapsulates a category
@@ -1068,8 +1081,9 @@ public:
return getName();
}
- static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCCategoryImplDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
};
/// ObjCImplementationDecl - Represents a class definition - this is where
@@ -1152,10 +1166,9 @@ public:
return ivar_begin() == ivar_end();
}
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCImplementation;
- }
+ 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; }
};
/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
@@ -1176,10 +1189,9 @@ public:
ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCCompatibleAlias;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
};
@@ -1294,10 +1306,9 @@ public:
return PropertyIvarDecl;
}
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCProperty;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCPropertyDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == ObjCProperty; }
};
/// ObjCPropertyImplDecl - Represents implementation declaration of a property
@@ -1354,10 +1365,9 @@ public:
}
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCPropertyImpl;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCPropertyImplDecl *D) { return true; }
+ static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
};
} // end namespace clang
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index d8b004a049ce..ced174716c7a 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -247,13 +247,14 @@ public:
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateDecl *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; }
+ static bool classofKind(Kind K) {
+ return K >= TemplateFirst && K <= TemplateLast;
+ }
protected:
NamedDecl *TemplatedDecl;
@@ -510,10 +511,9 @@ public:
NamedDecl *Decl);
// Implement isa/cast/dyncast support
- static bool classof(const Decl *D)
- { return D->getKind() == FunctionTemplate; }
- static bool classof(const FunctionTemplateDecl *D)
- { return true; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const FunctionTemplateDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == FunctionTemplate; }
};
//===----------------------------------------------------------------------===//
@@ -634,10 +634,9 @@ public:
bool isParameterPack() const { return ParameterPack; }
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == TemplateTypeParm;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateTypeParmDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == TemplateTypeParm; }
};
/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
@@ -682,10 +681,9 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == NonTypeTemplateParm;
- }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
};
/// TemplateTemplateParmDecl - Declares a template template parameter,
@@ -735,10 +733,9 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == TemplateTemplateParm;
- }
+ 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; }
};
/// \brief Represents a class template specialization, which refers to
@@ -903,9 +900,10 @@ public:
TemplateArgs[Arg].Profile(ID, Context);
}
- static bool classof(const Decl *D) {
- return D->getKind() == ClassTemplateSpecialization ||
- D->getKind() == ClassTemplatePartialSpecialization;
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K == ClassTemplateSpecialization ||
+ K == ClassTemplatePartialSpecialization;
}
static bool classof(const ClassTemplateSpecializationDecl *) {
@@ -1039,8 +1037,9 @@ public:
// FIXME: Add Profile support!
- static bool classof(const Decl *D) {
- return D->getKind() == ClassTemplatePartialSpecialization;
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K == ClassTemplatePartialSpecialization;
}
static bool classof(const ClassTemplatePartialSpecializationDecl *) {
@@ -1212,10 +1211,9 @@ public:
}
// Implement isa/cast/dyncast support
- static bool classof(const Decl *D)
- { return D->getKind() == ClassTemplate; }
- static bool classof(const ClassTemplateDecl *D)
- { return true; }
+ 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);
};
@@ -1293,9 +1291,8 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == Decl::FriendTemplate;
- }
+ 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; }
};
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 59d7e439e570..2254724410d0 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -274,30 +274,34 @@ public:
static DeclarationName getTombstoneMarker() {
return DeclarationName(uintptr_t(-2));
}
+
+ static int compare(DeclarationName LHS, DeclarationName RHS);
void dump() const;
};
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
-bool operator<(DeclarationName LHS, DeclarationName RHS);
+inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
+ return DeclarationName::compare(LHS, RHS) < 0;
+}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
- return RHS < LHS;
+ return DeclarationName::compare(LHS, RHS) > 0;
}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
- return !(RHS < LHS);
+ return DeclarationName::compare(LHS, RHS) <= 0;
}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
- return !(LHS < RHS);
+ return DeclarationName::compare(LHS, RHS) >= 0;
}
/// DeclarationNameTable - Used to store and retrieve DeclarationName
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 252781767169..114a19800f50 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -149,7 +149,8 @@ public:
LV_DuplicateVectorComponents,
LV_InvalidExpression,
LV_MemberFunction,
- LV_SubObjCPropertySetting
+ LV_SubObjCPropertySetting,
+ LV_SubObjCPropertyGetterSetting
};
isLvalueResult isLvalue(ASTContext &Ctx) const;
@@ -179,7 +180,8 @@ public:
MLV_ReadonlyProperty,
MLV_NoSetterProperty,
MLV_MemberFunction,
- MLV_SubObjCPropertySetting
+ MLV_SubObjCPropertySetting,
+ MLV_SubObjCPropertyGetterSetting
};
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
SourceLocation *Loc = 0) const;
@@ -192,6 +194,9 @@ public:
return const_cast<Expr*>(this)->getBitField();
}
+ /// \brief Returns whether this expression refers to a vector element.
+ bool refersToVectorElement() const;
+
/// isIntegerConstantExpr - Return true if this expression is a valid integer
/// constant expression, and, if so, return its value in Result. If not a
/// valid i-c-e, return false and fill in Loc (if specified) with the location
@@ -563,7 +568,10 @@ public:
enum IdentType {
Func,
Function,
- PrettyFunction
+ PrettyFunction,
+ /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
+ /// 'virtual' keyword is omitted for virtual member functions.
+ PrettyFunctionNoVirtual
};
private:
@@ -584,8 +592,7 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- static std::string ComputeName(ASTContext &Context, IdentType IT,
- const Decl *CurrentDecl);
+ static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
@@ -1745,7 +1752,7 @@ public:
static bool classof(const Stmt *T) {
StmtClass SC = T->getStmtClass();
- if (SC >= ExplicitCastExprClass && SC <= CStyleCastExprClass)
+ if (SC >= CStyleCastExprClass && SC <= CStyleCastExprClass)
return true;
if (SC >= CXXNamedCastExprClass && SC <= CXXFunctionalCastExprClass)
return true;
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 6ce95ac5227f..e4bc4b746439 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -241,10 +241,17 @@ public:
CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
Expr(CXXBoolLiteralExprClass, Ty, false, false), Value(val), Loc(l) {}
+ explicit CXXBoolLiteralExpr(EmptyShell Empty)
+ : Expr(CXXBoolLiteralExprClass, Empty) { }
+
bool getValue() const { return Value; }
+ void setValue(bool V) { Value = V; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXBoolLiteralExprClass;
}
@@ -262,8 +269,14 @@ public:
CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
Expr(CXXNullPtrLiteralExprClass, Ty, false, false), Loc(l) {}
+ explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
+ : Expr(CXXNullPtrLiteralExprClass, Empty) { }
+
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNullPtrLiteralExprClass;
}
@@ -544,6 +557,68 @@ 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. (Ans also 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);
+
+ 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() { 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();
+};
+
/// CXXConstructExpr - Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
CXXConstructorDecl *Constructor;
@@ -551,6 +626,7 @@ class CXXConstructExpr : public Expr {
SourceLocation Loc;
bool Elidable : 1;
bool ZeroInitialization : 1;
+ bool BaseInitialization : 1;
Stmt **Args;
unsigned NumArgs;
@@ -559,7 +635,8 @@ protected:
SourceLocation Loc,
CXXConstructorDecl *d, bool elidable,
Expr **args, unsigned numargs,
- bool ZeroInitialization = false);
+ bool ZeroInitialization = false,
+ bool BaseInitialization = false);
~CXXConstructExpr() { }
virtual void DoDestroy(ASTContext &C);
@@ -573,7 +650,8 @@ public:
SourceLocation Loc,
CXXConstructorDecl *D, bool Elidable,
Expr **Args, unsigned NumArgs,
- bool ZeroInitialization = false);
+ bool ZeroInitialization = false,
+ bool BaseInitialization = false);
CXXConstructorDecl* getConstructor() const { return Constructor; }
@@ -593,6 +671,11 @@ public:
ZeroInitialization = ZeroInit;
}
+ /// \brief Determines whether this constructor is actually constructing
+ /// a base class (rather than a complete object).
+ bool isBaseInitialization() const { return BaseInitialization; }
+ void setBaseInitialization(bool BI) { BaseInitialization = BI; }
+
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
@@ -779,15 +862,14 @@ class CXXNewExpr : public Expr {
SourceLocation EndLoc;
public:
- CXXNewExpr(bool globalNew, FunctionDecl *operatorNew, Expr **placementArgs,
- unsigned numPlaceArgs, bool ParenTypeId, Expr *arraySize,
- CXXConstructorDecl *constructor, bool initializer,
+ CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
+ Expr **placementArgs, unsigned numPlaceArgs, bool ParenTypeId,
+ Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
Expr **constructorArgs, unsigned numConsArgs,
FunctionDecl *operatorDelete, QualType ty,
SourceLocation startLoc, SourceLocation endLoc);
- ~CXXNewExpr() {
- delete[] SubExprs;
- }
+
+ virtual void DoDestroy(ASTContext &C);
QualType getAllocatedType() const {
assert(getType()->isPointerType());
@@ -1059,33 +1141,123 @@ public:
virtual child_iterator child_end();
};
-/// \brief A reference to a name which we were able to look up during
-/// parsing but could not resolve to a specific declaration. This
-/// arises in several ways:
-/// * we might be waiting for argument-dependent lookup
-/// * the name might resolve to an overloaded function
-/// and eventually:
-/// * the lookup might have included a function template
-/// These never include UnresolvedUsingValueDecls, which are always
-/// class members and therefore appear only in
-/// UnresolvedMemberLookupExprs.
-class UnresolvedLookupExpr : public Expr {
+/// \brief A reference to an overloaded function set, either an
+/// \t UnresolvedLookupExpr or an \t UnresolvedMemberExpr.
+class OverloadExpr : public Expr {
/// The results. These are undesugared, which is to say, they may
- /// include UsingShadowDecls.
+ /// include UsingShadowDecls. Access is relative to the naming
+ /// class.
UnresolvedSet<4> Results;
- /// The name declared.
+ /// The common name of these declarations.
DeclarationName Name;
- /// The qualifier given, if any.
+ /// The scope specifier, if any.
NestedNameSpecifier *Qualifier;
-
- /// The source range of the nested name specifier.
+
+ /// The source range of the scope specifier.
SourceRange QualifierRange;
/// The location of the name.
SourceLocation NameLoc;
+ /// True if the name was a template-id.
+ bool HasExplicitTemplateArgs;
+
+protected:
+ OverloadExpr(StmtClass K, QualType T, bool Dependent,
+ NestedNameSpecifier *Qualifier, SourceRange QRange,
+ DeclarationName Name, SourceLocation NameLoc,
+ bool HasTemplateArgs)
+ : Expr(K, T, Dependent, Dependent),
+ Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
+ NameLoc(NameLoc), HasExplicitTemplateArgs(HasTemplateArgs)
+ {}
+
+public:
+ /// Computes whether an unresolved lookup on the given declarations
+ /// and optional template arguments is type- and value-dependent.
+ static bool ComputeDependence(UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End,
+ const TemplateArgumentListInfo *Args);
+
+ /// 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) {
+ assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
+
+ bool op = false;
+ E = E->IgnoreParens();
+ if (isa<UnaryOperator>(E))
+ op = true, E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
+ return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(E), op);
+ }
+
+ void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
+ Results.append(Begin, End);
+ }
+
+ typedef UnresolvedSetImpl::iterator decls_iterator;
+ decls_iterator decls_begin() const { return Results.begin(); }
+ decls_iterator decls_end() const { return Results.end(); }
+
+ /// Gets the decls as an unresolved set.
+ const UnresolvedSetImpl &getDecls() { return Results; }
+
+ /// Gets the number of declarations in the unresolved set.
+ unsigned getNumDecls() const { return Results.size(); }
+
+ /// Gets the name looked up.
+ DeclarationName getName() const { return Name; }
+ void setName(DeclarationName N) { Name = N; }
+
+ /// Gets the location of the name.
+ SourceLocation getNameLoc() const { return NameLoc; }
+ void setNameLoc(SourceLocation Loc) { NameLoc = Loc; }
+
+ /// Fetches the nested-name qualifier, if one was given.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// Fetches the range of the nested-name qualifier.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief Determines whether this expression had an explicit
+ /// template argument list, e.g. f<int>.
+ bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs(); // defined far below
+
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs();
+ }
+
+ ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+ if (hasExplicitTemplateArgs())
+ return &getExplicitTemplateArgs();
+ return 0;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnresolvedLookupExprClass ||
+ T->getStmtClass() == UnresolvedMemberExprClass;
+ }
+ static bool classof(const OverloadExpr *) { return true; }
+};
+
+/// \brief A reference to a name which we were able to look up during
+/// parsing but could not resolve to a specific declaration. This
+/// arises in several ways:
+/// * we might be waiting for argument-dependent lookup
+/// * the name might resolve to an overloaded function
+/// and eventually:
+/// * the lookup might have included a function template
+/// These never include UnresolvedUsingValueDecls, which are always
+/// class members and therefore appear only in
+/// UnresolvedMemberLookupExprs.
+class UnresolvedLookupExpr : public OverloadExpr {
/// True if these lookup results should be extended by
/// argument-dependent lookup if this is the operand of a function
/// call.
@@ -1095,35 +1267,40 @@ class UnresolvedLookupExpr : public Expr {
/// trivially rederivable if we urgently need to kill this field.
bool Overloaded;
- /// True if the name looked up had explicit template arguments.
- /// This requires all the results to be function templates.
- bool HasExplicitTemplateArgs;
+ /// The naming class (C++ [class.access.base]p5) of the lookup, if
+ /// any. This can generally be recalculated from the context chain,
+ /// but that can be fairly expensive for unqualified lookups. If we
+ /// want to improve memory use here, this could go in a union
+ /// against the qualified-lookup bits.
+ CXXRecordDecl *NamingClass;
- UnresolvedLookupExpr(QualType T, bool Dependent,
+ UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier, SourceRange QRange,
DeclarationName Name, SourceLocation NameLoc,
bool RequiresADL, bool Overloaded, bool HasTemplateArgs)
- : Expr(UnresolvedLookupExprClass, T, Dependent, Dependent),
- Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
- NameLoc(NameLoc), RequiresADL(RequiresADL), Overloaded(Overloaded),
- HasExplicitTemplateArgs(HasTemplateArgs)
+ : OverloadExpr(UnresolvedLookupExprClass, T, Dependent, Qualifier, QRange,
+ Name, NameLoc, HasTemplateArgs),
+ RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
{}
public:
static UnresolvedLookupExpr *Create(ASTContext &C,
bool Dependent,
+ CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
DeclarationName Name,
SourceLocation NameLoc,
bool ADL, bool Overloaded) {
return new(C) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
- Dependent, Qualifier, QualifierRange,
+ Dependent, NamingClass,
+ Qualifier, QualifierRange,
Name, NameLoc, ADL, Overloaded, false);
}
static UnresolvedLookupExpr *Create(ASTContext &C,
bool Dependent,
+ CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
DeclarationName Name,
@@ -1131,20 +1308,6 @@ public:
bool ADL,
const TemplateArgumentListInfo &Args);
- /// Computes whether an unresolved lookup on the given declarations
- /// and optional template arguments is type- and value-dependent.
- static bool ComputeDependence(UnresolvedSetImpl::const_iterator Begin,
- UnresolvedSetImpl::const_iterator End,
- const TemplateArgumentListInfo *Args);
-
- void addDecl(NamedDecl *Decl) {
- Results.addDecl(Decl);
- }
-
- typedef UnresolvedSetImpl::iterator decls_iterator;
- decls_iterator decls_begin() const { return Results.begin(); }
- decls_iterator decls_end() const { return Results.end(); }
-
/// True if this declaration should be extended by
/// argument-dependent lookup.
bool requiresADL() const { return RequiresADL; }
@@ -1152,25 +1315,20 @@ public:
/// True if this lookup is overloaded.
bool isOverloaded() const { return Overloaded; }
- /// Fetches the name looked up.
- DeclarationName getName() const { return Name; }
-
- /// Gets the location of the name.
- SourceLocation getNameLoc() const { return NameLoc; }
-
- /// Fetches the nested-name qualifier, if one was given.
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
-
- /// Fetches the range of the nested-name qualifier.
- SourceRange getQualifierRange() const { return QualifierRange; }
-
- /// Determines whether this lookup had explicit template arguments.
- bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+ /// Gets the 'naming class' (in the sense of C++0x
+ /// [class.access.base]p5) of the lookup. This is the scope
+ /// that was looked in to find these results.
+ CXXRecordDecl *getNamingClass() const { return NamingClass; }
// Note that, inconsistently with the explicit-template-argument AST
// nodes, users are *forbidden* from calling these methods on objects
// without explicit template arguments.
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1);
+ }
+
/// Gets a reference to the explicit template argument list.
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
assert(hasExplicitTemplateArgs());
@@ -1200,8 +1358,8 @@ public:
}
virtual SourceRange getSourceRange() const {
- SourceRange Range(NameLoc);
- if (Qualifier) Range.setBegin(QualifierRange.getBegin());
+ SourceRange Range(getNameLoc());
+ if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
return Range;
}
@@ -1456,11 +1614,24 @@ public:
arg_iterator arg_begin() { return reinterpret_cast<Expr**>(this + 1); }
arg_iterator arg_end() { return arg_begin() + NumArgs; }
+ typedef const Expr* const * const_arg_iterator;
+ const_arg_iterator arg_begin() const {
+ return reinterpret_cast<const Expr* const *>(this + 1);
+ }
+ const_arg_iterator arg_end() const {
+ return arg_begin() + NumArgs;
+ }
+
Expr *getArg(unsigned I) {
assert(I < NumArgs && "Argument index out-of-range");
return *(arg_begin() + I);
}
+ const Expr *getArg(unsigned I) const {
+ assert(I < NumArgs && "Argument index out-of-range");
+ return *(arg_begin() + I);
+ }
+
virtual SourceRange getSourceRange() const {
return SourceRange(TyBeginLoc, RParenLoc);
}
@@ -1713,19 +1884,7 @@ public:
/// In the final AST, an explicit access always becomes a MemberExpr.
/// An implicit access may become either a MemberExpr or a
/// DeclRefExpr, depending on whether the member is static.
-class UnresolvedMemberExpr : public Expr {
- /// The results. These are undesugared, which is to say, they may
- /// include UsingShadowDecls.
- UnresolvedSet<4> Results;
-
- /// \brief The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f. This can be null if this is an 'unbased'
- /// member expression
- Stmt *Base;
-
- /// \brief The type of the base expression; never null.
- QualType BaseType;
-
+class UnresolvedMemberExpr : public OverloadExpr {
/// \brief Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
@@ -1734,39 +1893,17 @@ class UnresolvedMemberExpr : public Expr {
/// declaration.
bool HasUnresolvedUsing : 1;
- /// \brief Whether this member expression has explicitly-specified template
- /// arguments.
- bool HasExplicitTemplateArgs : 1;
+ /// \brief The expression for the base pointer or class reference,
+ /// e.g., the \c x in x.f. This can be null if this is an 'unbased'
+ /// member expression
+ Stmt *Base;
+
+ /// \brief The type of the base expression; never null.
+ QualType BaseType;
/// \brief The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
- /// \brief The nested-name-specifier that precedes the member name, if any.
- NestedNameSpecifier *Qualifier;
-
- /// \brief The source range covering the nested name specifier.
- SourceRange QualifierRange;
-
- /// \brief The member to which this member expression refers, which
- /// can be a name or an overloaded operator.
- DeclarationName MemberName;
-
- /// \brief The location of the member name.
- SourceLocation MemberLoc;
-
- /// \brief Retrieve the explicit template argument list that followed the
- /// member template name.
- ExplicitTemplateArgumentList *getExplicitTemplateArgs() {
- assert(HasExplicitTemplateArgs);
- return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
- }
-
- /// \brief Retrieve the explicit template argument list that followed the
- /// member template name, if any.
- const ExplicitTemplateArgumentList *getExplicitTemplateArgs() const {
- return const_cast<UnresolvedMemberExpr*>(this)->getExplicitTemplateArgs();
- }
-
UnresolvedMemberExpr(QualType T, bool Dependent,
bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
@@ -1788,19 +1925,6 @@ public:
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs);
- /// Adds a declaration to the unresolved set. By assumption, all of
- /// these happen at initialization time and properties like
- /// 'Dependent' and 'HasUnresolvedUsing' take them into account.
- void addDecl(NamedDecl *Decl) {
- Results.addDecl(Decl);
- }
-
- typedef UnresolvedSetImpl::iterator decls_iterator;
- decls_iterator decls_begin() const { return Results.begin(); }
- decls_iterator decls_end() const { return Results.end(); }
-
- unsigned getNumDecls() const { return Results.size(); }
-
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
@@ -1812,6 +1936,10 @@ public:
assert(!isImplicitAccess());
return cast<Expr>(Base);
}
+ const Expr *getBase() const {
+ assert(!isImplicitAccess());
+ return cast<Expr>(Base);
+ }
void setBase(Expr *E) { Base = E; }
QualType getBaseType() const { return BaseType; }
@@ -1825,57 +1953,60 @@ public:
SourceLocation getOperatorLoc() const { return OperatorLoc; }
void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
- /// \brief Retrieve the nested-name-specifier that qualifies the member
- /// name.
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
-
- /// \brief Retrieve the source range covering the nested-name-specifier
- /// that qualifies the member name.
- SourceRange getQualifierRange() const { return QualifierRange; }
+ /// \brief Retrieves the naming class of this lookup.
+ CXXRecordDecl *getNamingClass() const;
/// \brief Retrieve the name of the member that this expression
/// refers to.
- DeclarationName getMemberName() const { return MemberName; }
- void setMemberName(DeclarationName N) { MemberName = N; }
+ DeclarationName getMemberName() const { return getName(); }
+ void setMemberName(DeclarationName N) { setName(N); }
// \brief Retrieve the location of the name of the member that this
// expression refers to.
- SourceLocation getMemberLoc() const { return MemberLoc; }
- void setMemberLoc(SourceLocation L) { MemberLoc = L; }
+ SourceLocation getMemberLoc() const { return getNameLoc(); }
+ void setMemberLoc(SourceLocation L) { setNameLoc(L); }
- /// \brief Determines whether this member expression actually had a C++
- /// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgs() const {
- return HasExplicitTemplateArgs;
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name.
+ ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<const ExplicitTemplateArgumentList *>(this + 1);
}
/// \brief Copies the template arguments into the given structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- getExplicitTemplateArgs()->copyInto(List);
+ getExplicitTemplateArgs().copyInto(List);
}
/// \brief Retrieve the location of the left angle bracket following
/// the member name ('<').
SourceLocation getLAngleLoc() const {
- return getExplicitTemplateArgs()->LAngleLoc;
+ return getExplicitTemplateArgs().LAngleLoc;
}
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
- return getExplicitTemplateArgs()->getTemplateArgs();
+ return getExplicitTemplateArgs().getTemplateArgs();
}
/// \brief Retrieve the number of template arguments provided as
/// part of this template-id.
unsigned getNumTemplateArgs() const {
- return getExplicitTemplateArgs()->NumTemplateArgs;
+ return getExplicitTemplateArgs().NumTemplateArgs;
}
/// \brief Retrieve the location of the right angle bracket
/// following the template arguments ('>').
SourceLocation getRAngleLoc() const {
- return getExplicitTemplateArgs()->RAngleLoc;
+ return getExplicitTemplateArgs().RAngleLoc;
}
virtual SourceRange getSourceRange() const {
@@ -1885,12 +2016,12 @@ public:
else if (getQualifier())
Range.setBegin(getQualifierRange().getBegin());
else
- Range.setBegin(MemberLoc);
+ Range.setBegin(getMemberLoc());
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());
else
- Range.setEnd(MemberLoc);
+ Range.setEnd(getMemberLoc());
return Range;
}
@@ -1904,6 +2035,13 @@ public:
virtual child_iterator child_end();
};
+inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() {
+ if (isa<UnresolvedLookupExpr>(this))
+ return cast<UnresolvedLookupExpr>(this)->getExplicitTemplateArgs();
+ else
+ return cast<UnresolvedMemberExpr>(this)->getExplicitTemplateArgs();
+}
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index 0b0cd64ad721..df39b535eb3e 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -367,7 +367,7 @@ class ObjCMessageExpr : public Expr {
public:
/// This constructor is used to represent class messages where the
/// ObjCInterfaceDecl* of the receiver is not known.
- ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
+ ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
@@ -375,13 +375,13 @@ public:
/// This constructor is used to represent class messages where the
/// ObjCInterfaceDecl* of the receiver is known.
// FIXME: clsName should be typed to ObjCInterfaceType
- ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
+ ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
// constructor for instance messages.
- ObjCMessageExpr(Expr *receiver, Selector selInfo,
+ ObjCMessageExpr(ASTContext &C, Expr *receiver, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
@@ -389,9 +389,7 @@ public:
explicit ObjCMessageExpr(EmptyShell Empty)
: Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {}
- ~ObjCMessageExpr() {
- delete [] SubExprs;
- }
+ virtual void DoDestroy(ASTContext &C);
/// getReceiver - Returns the receiver of the message expression.
/// This can be NULL if the message is for class methods. For
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index d058f838a008..94caa6faad66 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -102,6 +102,7 @@ public:
#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class,
#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class,
#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class
+#define ABSTRACT_EXPR(CLASS, PARENT)
#include "clang/AST/StmtNodes.def"
};
private:
@@ -1120,21 +1121,27 @@ class AsmStmt : public Stmt {
unsigned NumOutputs;
unsigned NumInputs;
+ unsigned NumClobbers;
- llvm::SmallVector<std::string, 4> Names;
- llvm::SmallVector<StringLiteral*, 4> Constraints;
- llvm::SmallVector<Stmt*, 4> Exprs;
+ // FIXME: If we wanted to, we could allocate all of these in one big array.
+ IdentifierInfo **Names;
+ StringLiteral **Constraints;
+ Stmt **Exprs;
+ StringLiteral **Clobbers;
- llvm::SmallVector<StringLiteral*, 4> Clobbers;
+protected:
+ virtual void DoDestroy(ASTContext &Ctx);
+
public:
- AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, bool msasm,
- unsigned numoutputs, unsigned numinputs,
- std::string *names, StringLiteral **constraints,
+ AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
+ bool msasm, unsigned numoutputs, unsigned numinputs,
+ IdentifierInfo **names, StringLiteral **constraints,
Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
StringLiteral **clobbers, SourceLocation rparenloc);
/// \brief Build an empty inline-assembly statement.
- explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty) { }
+ explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty),
+ Names(0), Constraints(0), Exprs(0), Clobbers(0) { }
SourceLocation getAsmLoc() const { return AsmLoc; }
void setAsmLoc(SourceLocation L) { AsmLoc = L; }
@@ -1208,14 +1215,21 @@ public:
unsigned getNumOutputs() const { return NumOutputs; }
- const std::string &getOutputName(unsigned i) const {
+ IdentifierInfo *getOutputIdentifier(unsigned i) const {
return Names[i];
}
+ llvm::StringRef getOutputName(unsigned i) const {
+ if (IdentifierInfo *II = getOutputIdentifier(i))
+ return II->getName();
+
+ return llvm::StringRef();
+ }
+
/// getOutputConstraint - Return the constraint string for the specified
/// output operand. All output constraints are known to be non-empty (either
/// '=' or '+').
- std::string getOutputConstraint(unsigned i) const;
+ llvm::StringRef getOutputConstraint(unsigned i) const;
const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
return Constraints[i];
@@ -1224,7 +1238,6 @@ public:
return Constraints[i];
}
-
Expr *getOutputExpr(unsigned i);
const Expr *getOutputExpr(unsigned i) const {
@@ -1246,13 +1259,20 @@ public:
unsigned getNumInputs() const { return NumInputs; }
- const std::string &getInputName(unsigned i) const {
+ IdentifierInfo *getInputIdentifier(unsigned i) const {
return Names[i + NumOutputs];
}
+ llvm::StringRef getInputName(unsigned i) const {
+ if (IdentifierInfo *II = getInputIdentifier(i))
+ return II->getName();
+
+ return llvm::StringRef();
+ }
+
/// getInputConstraint - Return the specified input constraint. Unlike output
/// constraints, these can be empty.
- std::string getInputConstraint(unsigned i) const;
+ llvm::StringRef getInputConstraint(unsigned i) const;
const StringLiteral *getInputConstraintLiteral(unsigned i) const {
return Constraints[i + NumOutputs];
@@ -1261,32 +1281,31 @@ public:
return Constraints[i + NumOutputs];
}
-
Expr *getInputExpr(unsigned i);
const Expr *getInputExpr(unsigned i) const {
return const_cast<AsmStmt*>(this)->getInputExpr(i);
}
- void setOutputsAndInputs(unsigned NumOutputs,
- unsigned NumInputs,
- const std::string *Names,
- StringLiteral **Constraints,
- Stmt **Exprs);
+ void setOutputsAndInputsAndClobbers(ASTContext &C,
+ IdentifierInfo **Names,
+ StringLiteral **Constraints,
+ Stmt **Exprs,
+ unsigned NumOutputs,
+ unsigned NumInputs,
+ StringLiteral **Clobbers,
+ unsigned NumClobbers);
//===--- Other ---===//
/// getNamedOperand - Given a symbolic operand reference like %[foo],
/// translate this into a numeric value needed to reference the same operand.
/// This returns -1 if the operand name is invalid.
- int getNamedOperand(const std::string &SymbolicName) const;
-
+ int getNamedOperand(llvm::StringRef SymbolicName) const;
-
- unsigned getNumClobbers() const { return Clobbers.size(); }
+ unsigned getNumClobbers() const { return NumClobbers; }
StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
- void setClobbers(StringLiteral **Clobbers, unsigned NumClobbers);
virtual SourceRange getSourceRange() const {
return SourceRange(AsmLoc, RParenLoc);
@@ -1301,19 +1320,19 @@ public:
typedef ConstExprIterator const_inputs_iterator;
inputs_iterator begin_inputs() {
- return Exprs.data() + NumOutputs;
+ return &Exprs[0] + NumOutputs;
}
inputs_iterator end_inputs() {
- return Exprs.data() + NumOutputs + NumInputs;
+ return &Exprs[0] + NumOutputs + NumInputs;
}
const_inputs_iterator begin_inputs() const {
- return Exprs.data() + NumOutputs;
+ return &Exprs[0] + NumOutputs;
}
const_inputs_iterator end_inputs() const {
- return Exprs.data() + NumOutputs + NumInputs;
+ return &Exprs[0] + NumOutputs + NumInputs;
}
// Output expr iterators.
@@ -1322,27 +1341,17 @@ public:
typedef ConstExprIterator const_outputs_iterator;
outputs_iterator begin_outputs() {
- return Exprs.data();
+ return &Exprs[0];
}
outputs_iterator end_outputs() {
- return Exprs.data() + NumOutputs;
+ return &Exprs[0] + NumOutputs;
}
const_outputs_iterator begin_outputs() const {
- return Exprs.data();
+ return &Exprs[0];
}
const_outputs_iterator end_outputs() const {
- return Exprs.data() + NumOutputs;
- }
-
- // Input name iterator.
-
- const std::string *begin_output_names() const {
- return &Names[0];
- }
-
- const std::string *end_output_names() const {
- return &Names[0] + NumOutputs;
+ return &Exprs[0] + NumOutputs;
}
// Child iterators
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 09ea4ca2101b..4e87c2701c26 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -59,31 +59,42 @@ public:
///
class CXXTryStmt : public Stmt {
SourceLocation TryLoc;
- // First place is the guarded CompoundStatement. Subsequent are the handlers.
- // More than three handlers should be rare.
- llvm::SmallVector<Stmt*, 4> Stmts;
+ unsigned NumHandlers;
+
+ CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
+ unsigned numHandlers);
public:
- CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
- Stmt **handlers, unsigned numHandlers);
+ static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
+ Stmt *tryBlock, Stmt **handlers,
+ unsigned numHandlers);
virtual SourceRange getSourceRange() const {
return SourceRange(getTryLoc(), getEndLoc());
}
SourceLocation getTryLoc() const { return TryLoc; }
- SourceLocation getEndLoc() const { return Stmts.back()->getLocEnd(); }
+ SourceLocation getEndLoc() const {
+ Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
+ return Stmts[NumHandlers]->getLocEnd();
+ }
- CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); }
+ CompoundStmt *getTryBlock() {
+ Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
+ return llvm::cast<CompoundStmt>(Stmts[0]);
+ }
const CompoundStmt *getTryBlock() const {
+ Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
return llvm::cast<CompoundStmt>(Stmts[0]);
}
- unsigned getNumHandlers() const { return Stmts.size() - 1; }
+ unsigned getNumHandlers() const { return NumHandlers; }
CXXCatchStmt *getHandler(unsigned i) {
+ Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
return llvm::cast<CXXCatchStmt>(Stmts[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]);
}
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index 7102336180cf..ec6149e55f11 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -68,8 +68,7 @@ STMT(CXXTryStmt , Stmt)
LAST_STMT(CXXTryStmt)
// Expressions.
-ABSTRACT_EXPR(Expr , Stmt)
-FIRST_EXPR(Expr)
+ABSTRACT_EXPR(Expr , Stmt)
EXPR(PredefinedExpr , Expr)
EXPR(DeclRefExpr , Expr)
EXPR(IntegerLiteral , Expr)
@@ -83,12 +82,12 @@ EXPR(SizeOfAlignOfExpr , Expr)
EXPR(ArraySubscriptExpr , Expr)
EXPR(CallExpr , Expr)
EXPR(MemberExpr , Expr)
-EXPR(CastExpr , Expr)
+ABSTRACT_EXPR(CastExpr , Expr)
EXPR(BinaryOperator , Expr)
EXPR(CompoundAssignOperator, BinaryOperator)
EXPR(ConditionalOperator , Expr)
EXPR(ImplicitCastExpr , CastExpr)
-EXPR(ExplicitCastExpr , CastExpr)
+ABSTRACT_EXPR(ExplicitCastExpr, CastExpr)
EXPR(CStyleCastExpr , ExplicitCastExpr)
EXPR(CompoundLiteralExpr , Expr)
EXPR(ExtVectorElementExpr , Expr)
@@ -129,6 +128,7 @@ EXPR(UnaryTypeTraitExpr , Expr)
EXPR(DependentScopeDeclRefExpr , Expr)
EXPR(CXXConstructExpr , Expr)
EXPR(CXXBindTemporaryExpr , Expr)
+EXPR(CXXBindReferenceExpr , Expr)
EXPR(CXXExprWithTemporaries , Expr)
EXPR(CXXTemporaryObjectExpr , CXXConstructExpr)
EXPR(CXXUnresolvedConstructExpr, Expr)
@@ -152,6 +152,7 @@ EXPR(ShuffleVectorExpr , Expr)
EXPR(BlockExpr , Expr)
EXPR(BlockDeclRefExpr , Expr)
+FIRST_EXPR(PredefinedExpr)
LAST_EXPR(BlockDeclRefExpr)
#undef ABSTRACT_EXPR
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
index 3a525507dad3..4986f08ac124 100644
--- a/include/clang/AST/StmtVisitor.h
+++ b/include/clang/AST/StmtVisitor.h
@@ -105,6 +105,7 @@ public:
// Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
switch (S->getStmtClass()) {
default: assert(0 && "Unknown stmt kind!");
+#define ABSTRACT_EXPR(CLASS, PARENT)
#define STMT(CLASS, PARENT) \
case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
#include "clang/AST/StmtNodes.def"
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index b7b60df5acb4..40e50988e6d2 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -16,6 +16,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Linkage.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "llvm/Support/Casting.h"
@@ -750,24 +751,22 @@ class Type {
public:
enum TypeClass {
#define TYPE(Class, Base) Class,
+#define LAST_TYPE(Class) TypeLast = Class,
#define ABSTRACT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
TagFirst = Record, TagLast = Enum
};
-protected:
- enum { TypeClassBitSize = 6 };
-
private:
QualType CanonicalType;
- /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
- bool Dependent : 1;
-
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
+ unsigned TC : 8;
+
+ /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
/// Note that this should stay at the end of the ivars for Type so that
/// subclasses can pack their bitfields into the same word.
- unsigned TC : TypeClassBitSize;
+ bool Dependent : 1;
Type(const Type&); // DO NOT IMPLEMENT.
void operator=(const Type&); // DO NOT IMPLEMENT.
@@ -776,7 +775,7 @@ protected:
Type *this_() { return this; }
Type(TypeClass tc, QualType Canonical, bool dependent)
: CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
- Dependent(dependent), TC(tc) {}
+ TC(tc), Dependent(dependent) {}
virtual ~Type() {}
virtual void Destroy(ASTContext& C);
friend class ASTContext;
@@ -974,6 +973,9 @@ public:
const char *getTypeClassName() const;
+ /// \brief Determine the linkage of this type.
+ virtual Linkage getLinkage() const;
+
QualType getCanonicalTypeInternal() const { return CanonicalType; }
void dump() const;
static bool classof(const Type *) { return true; }
@@ -1062,6 +1064,8 @@ public:
return TypeKind >= Float && TypeKind <= LongDouble;
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
static bool classof(const BuiltinType *) { return true; }
};
@@ -1089,6 +1093,8 @@ public:
ID.AddPointer(Element.getAsOpaquePtr());
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
static bool classof(const ComplexType *) { return true; }
};
@@ -1116,6 +1122,8 @@ public:
ID.AddPointer(Pointee.getAsOpaquePtr());
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
static bool classof(const PointerType *) { return true; }
};
@@ -1146,6 +1154,8 @@ public:
ID.AddPointer(Pointee.getAsOpaquePtr());
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == BlockPointer;
}
@@ -1183,7 +1193,8 @@ protected:
}
public:
bool isSpelledAsLValue() const { return SpelledAsLValue; }
-
+ bool isInnerRef() const { return InnerRef; }
+
QualType getPointeeTypeAsWritten() const { return PointeeType; }
QualType getPointeeType() const {
// FIXME: this might strip inner qualifiers; okay?
@@ -1203,6 +1214,8 @@ public:
ID.AddBoolean(SpelledAsLValue);
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == LValueReference ||
T->getTypeClass() == RValueReference;
@@ -1277,6 +1290,8 @@ public:
ID.AddPointer(Class);
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == MemberPointer;
}
@@ -1328,6 +1343,8 @@ public:
}
unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; }
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray ||
T->getTypeClass() == VariableArray ||
@@ -1576,7 +1593,8 @@ public:
/// VectorType - GCC generic vector type. This type is created using
/// __attribute__((vector_size(n)), where "n" specifies the vector size in
-/// bytes. Since the constructor takes the number of vector elements, the
+/// bytes; or from an Altivec __vector or vector declaration.
+/// Since the constructor takes the number of vector elements, the
/// client is responsible for converting the size into the number of elements.
class VectorType : public Type, public llvm::FoldingSetNode {
protected:
@@ -1586,13 +1604,21 @@ protected:
/// NumElements - The number of elements in the vector.
unsigned NumElements;
- VectorType(QualType vecType, unsigned nElements, QualType canonType) :
+ /// AltiVec - True if this is for an Altivec vector.
+ bool AltiVec;
+
+ /// Pixel - True if this is for an Altivec vector pixel.
+ bool Pixel;
+
+ VectorType(QualType vecType, unsigned nElements, QualType canonType,
+ bool isAltiVec, bool isPixel) :
Type(Vector, canonType, vecType->isDependentType()),
- ElementType(vecType), NumElements(nElements) {}
+ ElementType(vecType), NumElements(nElements),
+ AltiVec(isAltiVec), Pixel(isPixel) {}
VectorType(TypeClass tc, QualType vecType, unsigned nElements,
- QualType canonType)
+ QualType canonType, bool isAltiVec, bool isPixel)
: Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
- NumElements(nElements) {}
+ NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {}
friend class ASTContext; // ASTContext creates these.
public:
@@ -1602,15 +1628,26 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
+ bool isAltiVec() const { return AltiVec; }
+
+ bool isPixel() const { return Pixel; }
+
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getNumElements(), getTypeClass());
+ Profile(ID, getElementType(), getNumElements(), getTypeClass(),
+ AltiVec, Pixel);
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
- unsigned NumElements, TypeClass TypeClass) {
+ unsigned NumElements, TypeClass TypeClass,
+ bool isAltiVec, bool isPixel) {
ID.AddPointer(ElementType.getAsOpaquePtr());
ID.AddInteger(NumElements);
ID.AddInteger(TypeClass);
+ ID.AddBoolean(isAltiVec);
+ ID.AddBoolean(isPixel);
}
+
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
}
@@ -1624,7 +1661,7 @@ public:
/// points, colors, and textures (modeled after OpenGL Shading Language).
class ExtVectorType : public VectorType {
ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
- VectorType(ExtVector, vecType, nElements, canonType) {}
+ VectorType(ExtVector, vecType, nElements, canonType, false, false) {}
friend class ASTContext; // ASTContext creates these.
public:
static int getPointAccessorIdx(char c) {
@@ -1723,6 +1760,8 @@ public:
bool getNoReturnAttr() const { return NoReturn; }
CallingConv getCallConv() const { return (CallingConv)CallConv; }
+ static llvm::StringRef getNameForCallConv(CallingConv CC);
+
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto ||
T->getTypeClass() == FunctionProto;
@@ -1745,14 +1784,17 @@ public:
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getResultType(), getNoReturnAttr());
+ Profile(ID, getResultType(), getNoReturnAttr(), getCallConv());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
- bool NoReturn) {
+ bool NoReturn, CallingConv CallConv) {
+ ID.AddInteger(CallConv);
ID.AddInteger(NoReturn);
ID.AddPointer(ResultType.getAsOpaquePtr());
}
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto;
}
@@ -1856,6 +1898,8 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionProto;
}
@@ -1867,7 +1911,7 @@ public:
bool isVariadic, unsigned TypeQuals,
bool hasExceptionSpec, bool anyExceptionSpec,
unsigned NumExceptions, exception_iterator Exs,
- bool NoReturn);
+ bool NoReturn, CallingConv CallConv);
};
@@ -1878,8 +1922,9 @@ public:
class UnresolvedUsingType : public Type {
UnresolvedUsingTypenameDecl *Decl;
- UnresolvedUsingType(UnresolvedUsingTypenameDecl *D)
- : Type(UnresolvedUsing, QualType(), true), Decl(D) {}
+ UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
+ : Type(UnresolvedUsing, QualType(), true),
+ Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
friend class ASTContext; // ASTContext creates these.
public:
@@ -1906,8 +1951,9 @@ public:
class TypedefType : public Type {
TypedefDecl *Decl;
protected:
- TypedefType(TypeClass tc, TypedefDecl *D, QualType can)
- : Type(tc, can, can->isDependentType()), Decl(D) {
+ TypedefType(TypeClass tc, const TypedefDecl *D, QualType can)
+ : Type(tc, can, can->isDependentType()),
+ Decl(const_cast<TypedefDecl*>(D)) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
friend class ASTContext; // ASTContext creates these.
@@ -1950,8 +1996,12 @@ public:
static bool classof(const TypeOfExprType *) { return true; }
};
-/// Subclass of TypeOfExprType that is used for canonical, dependent
+/// \brief Internal representation of canonical, dependent
/// typeof(expr) types.
+///
+/// This class is used internally by the ASTContext to manage
+/// canonical, dependent types, only. Clients will only see instances
+/// of this class via TypeOfExprType nodes.
class DependentTypeOfExprType
: public TypeOfExprType, public llvm::FoldingSetNode {
ASTContext &Context;
@@ -2018,8 +2068,12 @@ public:
static bool classof(const DecltypeType *) { return true; }
};
-/// Subclass of DecltypeType that is used for canonical, dependent
-/// C++0x decltype types.
+/// \brief Internal representation of canonical, dependent
+/// decltype(expr) types.
+///
+/// This class is used internally by the ASTContext to manage
+/// canonical, dependent types, only. Clients will only see instances
+/// of this class via DecltypeType nodes.
class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
ASTContext &Context;
@@ -2048,7 +2102,7 @@ class TagType : public Type {
friend class TagDecl;
protected:
- TagType(TypeClass TC, TagDecl *D, QualType can);
+ TagType(TypeClass TC, const TagDecl *D, QualType can);
public:
TagDecl *getDecl() const { return decl.getPointer(); }
@@ -2058,6 +2112,8 @@ public:
bool isBeingDefined() const { return decl.getInt(); }
void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
+ virtual Linkage getLinkage() const;
+
static bool classof(const Type *T) {
return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
}
@@ -2070,10 +2126,10 @@ public:
/// to detect TagType objects of structs/unions/classes.
class RecordType : public TagType {
protected:
- explicit RecordType(RecordDecl *D)
- : TagType(Record, reinterpret_cast<TagDecl*>(D), QualType()) { }
+ explicit RecordType(const RecordDecl *D)
+ : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { }
explicit RecordType(TypeClass TC, RecordDecl *D)
- : TagType(TC, reinterpret_cast<TagDecl*>(D), QualType()) { }
+ : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { }
friend class ASTContext; // ASTContext creates these.
public:
@@ -2103,8 +2159,8 @@ public:
/// EnumType - This is a helper class that allows the use of isa/cast/dyncast
/// to detect TagType objects of enums.
class EnumType : public TagType {
- explicit EnumType(EnumDecl *D)
- : TagType(Enum, reinterpret_cast<TagDecl*>(D), QualType()) { }
+ explicit EnumType(const EnumDecl *D)
+ : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { }
friend class ASTContext; // ASTContext creates these.
public:
@@ -2512,12 +2568,12 @@ public:
class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
ObjCInterfaceDecl *Decl;
- // List of protocols for this protocol conforming object type
- // List is sorted on protocol name. No protocol is enterred more than once.
- ObjCProtocolDecl **Protocols;
+ /// \brief The number of protocols stored after the ObjCInterfaceType node.
+ /// The list of protocols is sorted on protocol name. No protocol is enterred
+ /// more than once.
unsigned NumProtocols;
- ObjCInterfaceType(ASTContext &Ctx, QualType Canonical, ObjCInterfaceDecl *D,
+ ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
ObjCProtocolDecl **Protos, unsigned NumP);
friend class ASTContext; // ASTContext creates these.
public:
@@ -2529,14 +2585,20 @@ public:
/// interface type, or 0 if there are none.
unsigned getNumProtocols() const { return NumProtocols; }
+ /// \brief Retrieve the Ith protocol.
+ ObjCProtocolDecl *getProtocol(unsigned I) const {
+ assert(I < getNumProtocols() && "Out-of-range protocol access");
+ return qual_begin()[I];
+ }
+
/// qual_iterator and friends: this provides access to the (potentially empty)
/// list of protocols qualifying this interface.
typedef ObjCProtocolDecl* const * qual_iterator;
qual_iterator qual_begin() const {
- return Protocols;
+ return reinterpret_cast<qual_iterator>(this + 1);
}
qual_iterator qual_end() const {
- return Protocols ? Protocols + NumProtocols : 0;
+ return qual_begin() + NumProtocols;
}
bool qual_empty() const { return NumProtocols == 0; }
@@ -2546,7 +2608,10 @@ public:
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID,
const ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl **protocols, unsigned NumProtocols);
+ ObjCProtocolDecl * const *protocols,
+ unsigned NumProtocols);
+
+ virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCInterface;
@@ -2562,12 +2627,14 @@ public:
class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType; // A builtin or interface type.
- // List of protocols for this protocol conforming object type
- // List is sorted on protocol name. No protocol is entered more than once.
- ObjCProtocolDecl **Protocols;
+ /// \brief The number of protocols stored after the ObjCObjectPointerType
+ /// node.
+ ///
+ /// The list of protocols is sorted on protocol name. No protocol is enterred
+ /// more than once.
unsigned NumProtocols;
- ObjCObjectPointerType(ASTContext &Ctx, QualType Canonical, QualType T,
+ ObjCObjectPointerType(QualType Canonical, QualType T,
ObjCProtocolDecl **Protos, unsigned NumP);
friend class ASTContext; // ASTContext creates these.
@@ -2614,10 +2681,10 @@ public:
typedef ObjCProtocolDecl* const * qual_iterator;
qual_iterator qual_begin() const {
- return Protocols;
+ return reinterpret_cast<qual_iterator> (this + 1);
}
qual_iterator qual_end() const {
- return Protocols ? Protocols + NumProtocols : NULL;
+ return qual_begin() + NumProtocols;
}
bool qual_empty() const { return NumProtocols == 0; }
@@ -2625,12 +2692,21 @@ public:
/// interface type, or 0 if there are none.
unsigned getNumProtocols() const { return NumProtocols; }
+ /// \brief Retrieve the Ith protocol.
+ ObjCProtocolDecl *getProtocol(unsigned I) const {
+ assert(I < getNumProtocols() && "Out-of-range protocol access");
+ return qual_begin()[I];
+ }
+
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
+ virtual Linkage getLinkage() const;
+
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
- ObjCProtocolDecl **protocols, unsigned NumProtocols);
+ ObjCProtocolDecl *const *protocols,
+ unsigned NumProtocols);
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCObjectPointer;
}
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 575011a8724c..9cf2cb7bd773 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -87,6 +87,11 @@ DEPENDENT_TYPE(Typename, Type)
TYPE(ObjCInterface, Type)
TYPE(ObjCObjectPointer, Type)
+#ifdef LAST_TYPE
+LAST_TYPE(ObjCObjectPointer)
+#undef LAST_TYPE
+#endif
+
// These types are always leaves in the type hierarchy.
#ifdef LEAF_TYPE
LEAF_TYPE(Enum)
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 055d15264674..9c59229e3134 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -16,7 +16,6 @@
#define LLVM_CLANG_AST_UNRESOLVEDSET_H
#include <iterator>
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "clang/Basic/Specifiers.h"
@@ -24,12 +23,58 @@ namespace clang {
class NamedDecl;
+/// A POD class for pairing a NamedDecl* with an access specifier.
+/// Can be put into unions.
+class DeclAccessPair {
+ NamedDecl *Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
+
+ enum { Mask = 0x3 };
+
+public:
+ static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
+ DeclAccessPair p;
+ p.set(D, AS);
+ return p;
+ }
+
+ NamedDecl *getDecl() const {
+ return (NamedDecl*) (~Mask & (uintptr_t) Ptr);
+ }
+ AccessSpecifier getAccess() const {
+ return AccessSpecifier(Mask & (uintptr_t) Ptr);
+ }
+
+ void setDecl(NamedDecl *D) {
+ set(D, getAccess());
+ }
+ void setAccess(AccessSpecifier AS) {
+ set(getDecl(), AS);
+ }
+ void set(NamedDecl *D, AccessSpecifier AS) {
+ Ptr = reinterpret_cast<NamedDecl*>(uintptr_t(AS) |
+ reinterpret_cast<uintptr_t>(D));
+ }
+
+ operator NamedDecl*() const { return getDecl(); }
+ NamedDecl *operator->() const { return getDecl(); }
+};
+}
+
+// Take a moment to tell SmallVector that this is POD.
+namespace llvm {
+template<typename> struct isPodLike;
+template<> struct isPodLike<clang::DeclAccessPair> {
+ static const bool value = true;
+};
+}
+
+namespace clang {
+
/// The iterator over UnresolvedSets. Serves as both the const and
/// non-const iterator.
class UnresolvedSetIterator {
-
- typedef llvm::PointerIntPair<NamedDecl*, 2> DeclEntry;
- typedef llvm::SmallVectorImpl<DeclEntry> DeclsTy;
+private:
+ typedef llvm::SmallVectorImpl<DeclAccessPair> DeclsTy;
typedef DeclsTy::iterator IteratorTy;
IteratorTy ir;
@@ -47,8 +92,8 @@ public:
typedef NamedDecl *reference;
typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category;
- NamedDecl *getDecl() const { return ir->getPointer(); }
- AccessSpecifier getAccess() const { return AccessSpecifier(ir->getInt()); }
+ NamedDecl *getDecl() const { return ir->getDecl(); }
+ AccessSpecifier getAccess() const { return ir->getAccess(); }
NamedDecl *operator*() const { return getDecl(); }
@@ -87,7 +132,6 @@ public:
/// in a lot of places, but isn't really worth breaking into its own
/// header right now.
class UnresolvedSetImpl {
- typedef UnresolvedSetIterator::DeclEntry DeclEntry;
typedef UnresolvedSetIterator::DeclsTy DeclsTy;
// Don't allow direct construction, and only permit subclassing by
@@ -114,7 +158,7 @@ public:
}
void addDecl(NamedDecl *D, AccessSpecifier AS) {
- decls().push_back(DeclEntry(D, AS));
+ decls().push_back(DeclAccessPair::make(D, AS));
}
/// Replaces the given declaration with the new one, once.
@@ -122,19 +166,24 @@ public:
/// \return true if the set changed
bool replace(const NamedDecl* Old, NamedDecl *New) {
for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
- if (I->getPointer() == Old)
- return (I->setPointer(New), true);
+ if (I->getDecl() == Old)
+ return (I->setDecl(New), true);
return false;
}
/// Replaces the declaration at the given iterator with the new one,
/// preserving the original access bits.
void replace(iterator I, NamedDecl *New) {
- I.ir->setPointer(New);
+ I.ir->setDecl(New);
}
void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
- *I.ir = DeclEntry(New, AS);
+ I.ir->set(New, AS);
+ }
+
+ void erase(unsigned I) {
+ decls()[I] = decls().back();
+ decls().pop_back();
}
void erase(iterator I) {
@@ -142,6 +191,10 @@ public:
decls().pop_back();
}
+ void setAccess(iterator I, AccessSpecifier AS) {
+ I.ir->setAccess(AS);
+ }
+
void clear() { decls().clear(); }
void set_size(unsigned N) { decls().set_size(N); }
@@ -152,41 +205,8 @@ public:
decls().append(I.ir, E.ir);
}
- /// A proxy reference for implementing operator[].
- class Proxy {
- DeclEntry &Ref;
-
- friend class UnresolvedSetImpl;
- Proxy(DeclEntry &Ref) : Ref(Ref) {}
-
- public:
- NamedDecl *getDecl() const { return Ref.getPointer(); }
- void setDecl(NamedDecl *D) { Ref.setPointer(D); }
-
- AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); }
- void setAccess(AccessSpecifier AS) const { Ref.setInt(AS); }
-
- NamedDecl* operator->() const { return getDecl(); }
- operator NamedDecl*() const { return getDecl(); }
- Proxy &operator=(const Proxy &D) { Ref = D.Ref; return *this; }
- };
- Proxy operator[](unsigned I) { return Proxy(decls()[I]); }
-
- /// A proxy reference for implementing operator[] const.
- class ConstProxy {
- const DeclEntry &Ref;
-
- friend class UnresolvedSetImpl;
- ConstProxy(const DeclEntry &Ref) : Ref(Ref) {}
-
- public:
- NamedDecl *getDecl() const { return Ref.getPointer(); }
- AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); }
-
- NamedDecl *operator->() const { return getDecl(); }
- operator NamedDecl*() const { return getDecl(); }
- };
- ConstProxy operator[](unsigned I) const { return ConstProxy(decls()[I]); }
+ DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
+ const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
private:
// These work because the only permitted subclass is UnresolvedSetImpl
@@ -202,7 +222,7 @@ private:
/// A set of unresolved declarations
template <unsigned InlineCapacity> class UnresolvedSet :
public UnresolvedSetImpl {
- llvm::SmallVector<UnresolvedSetImpl::DeclEntry, InlineCapacity> Decls;
+ llvm::SmallVector<DeclAccessPair, InlineCapacity> Decls;
};