summaryrefslogtreecommitdiffstats
path: root/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTContext.h35
-rw-r--r--include/clang/AST/Attr.h42
-rw-r--r--include/clang/AST/Decl.h46
-rw-r--r--include/clang/AST/DeclBase.h4
-rw-r--r--include/clang/AST/DeclCXX.h41
-rw-r--r--include/clang/AST/DeclTemplate.h3
-rw-r--r--include/clang/AST/DeclarationName.h26
-rw-r--r--include/clang/AST/Expr.h86
-rw-r--r--include/clang/AST/ExprCXX.h626
-rw-r--r--include/clang/AST/RecordLayout.h112
-rw-r--r--include/clang/AST/Redeclarable.h13
-rw-r--r--include/clang/AST/Stmt.h95
-rw-r--r--include/clang/AST/StmtCXX.h6
-rw-r--r--include/clang/AST/StmtNodes.def9
-rw-r--r--include/clang/AST/TemplateBase.h36
-rw-r--r--include/clang/AST/Type.h30
16 files changed, 868 insertions, 342 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index f9d2f71..4f29e5d 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -120,8 +120,7 @@ class ASTContext {
QualType ObjCIdTypedefType;
/// ObjCSelType - another pseudo built-in typedef type (set by Sema).
- QualType ObjCSelType;
- const RecordType *SelStructType;
+ QualType ObjCSelTypedefType;
/// ObjCProtoType - another pseudo built-in typedef type (set by Sema).
QualType ObjCProtoType;
@@ -244,6 +243,7 @@ public:
// pseudo-builtins
QualType ObjCIdRedefinitionType;
QualType ObjCClassRedefinitionType;
+ QualType ObjCSelRedefinitionType;
/// \brief Source ranges for all of the comments in the source file,
/// sorted in order of appearance in the translation unit.
@@ -316,7 +316,7 @@ public:
CanQualType OverloadTy;
CanQualType DependentTy;
CanQualType UndeducedAutoTy;
- CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy;
+ CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,
IdentifierTable &idents, SelectorTable &sels,
@@ -532,8 +532,7 @@ public:
QualType Canon = QualType());
QualType getTemplateSpecializationType(TemplateName T,
- const TemplateArgumentLoc *Args,
- unsigned NumArgs,
+ const TemplateArgumentListInfo &Args,
QualType Canon = QualType());
QualType getQualifiedNameType(NestedNameSpecifier *NNS,
@@ -696,7 +695,7 @@ public:
void setObjCIdType(QualType T);
void setObjCSelType(QualType T);
- QualType getObjCSelType() const { return ObjCSelType; }
+ QualType getObjCSelType() const { return ObjCSelTypedefType; }
void setObjCProtoType(QualType QT);
QualType getObjCProtoType() const { return ObjCProtoType; }
@@ -734,6 +733,8 @@ public:
return getExtQualType(T, Qs);
}
+ DeclarationName getNameForTemplate(TemplateName Name);
+
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
bool TemplateKeyword,
TemplateDecl *Template);
@@ -796,6 +797,20 @@ public:
return getTypeInfo(T).first;
}
+ /// getByteWidth - Return the size of a byte, in bits
+ uint64_t getByteSize() {
+ return getTypeSize(CharTy);
+ }
+
+ /// getTypeSizeInBytes - Return the size of the specified type, in bytes.
+ /// This method does not work on incomplete types.
+ uint64_t getTypeSizeInBytes(QualType T) {
+ return getTypeSize(T) / getByteSize();
+ }
+ uint64_t getTypeSizeInBytes(const Type *T) {
+ return getTypeSize(T) / getByteSize();
+ }
+
/// getTypeAlign - Return the ABI-specified alignment of a type, in bits.
/// This method does not work on incomplete types.
unsigned getTypeAlign(QualType T) {
@@ -811,10 +826,7 @@ public:
/// a data type.
unsigned getPreferredTypeAlign(const Type *T);
- /// getDeclAlignInBytes - Return the alignment of the specified decl
- /// that should be returned by __alignof(). Note that bitfields do
- /// not have a valid alignment, so this method will assert on them.
- unsigned getDeclAlignInBytes(const Decl *D);
+ unsigned getDeclAlignInBytes(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
@@ -1023,8 +1035,7 @@ public:
return T == ObjCClassTypedefType;
}
bool isObjCSelType(QualType T) const {
- assert(SelStructType && "isObjCSelType used before 'SEL' type is built");
- return T->getAsStructureType() == SelStructType;
+ return T == ObjCSelTypedefType;
}
bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS);
bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index b36ff12..2c7ab9d 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -15,12 +15,12 @@
#define LLVM_CLANG_AST_ATTR_H
#include "llvm/Support/Casting.h"
-using llvm::dyn_cast;
-
+#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <cstring>
#include <string>
#include <algorithm>
+using llvm::dyn_cast;
namespace clang {
class ASTContext;
@@ -49,6 +49,7 @@ public:
AnalyzerNoReturn, // Clang-specific.
Annotate,
AsmLabel, // Represent GCC asm label extension.
+ BaseCheck,
Blocks,
CDecl,
Cleanup,
@@ -59,9 +60,11 @@ public:
Deprecated,
Destructor,
FastCall,
+ Final,
Format,
FormatArg,
GNUInline,
+ Hiding,
IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with
Malloc,
NoDebug,
@@ -71,6 +74,7 @@ public:
NoThrow,
ObjCException,
ObjCNSObject,
+ Override,
CFReturnsRetained, // Clang/Checker-specific.
NSReturnsRetained, // Clang/Checker-specific.
Overloadable, // Clang-specific
@@ -184,12 +188,24 @@ public:
class AlignedAttr : public Attr {
unsigned Alignment;
public:
- AlignedAttr(unsigned alignment) : Attr(Aligned), Alignment(alignment) {}
+ AlignedAttr(unsigned alignment)
+ : Attr(Aligned), Alignment(alignment) {}
/// getAlignment - The specified alignment in bits.
unsigned getAlignment() const { return Alignment; }
+
+ /// getMaxAlignment - Get the maximum alignment of attributes on this list.
+ unsigned getMaxAlignment() const {
+ const AlignedAttr *Next = getNext<AlignedAttr>();
+ if (Next)
+ return std::max(Next->getMaxAlignment(), Alignment);
+ else
+ return Alignment;
+ }
- virtual Attr* clone(ASTContext &C) const { return ::new (C) AlignedAttr(Alignment); }
+ virtual Attr* clone(ASTContext &C) const {
+ return ::new (C) AlignedAttr(Alignment);
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
@@ -201,7 +217,7 @@ public:
class AnnotateAttr : public Attr {
std::string Annotation;
public:
- AnnotateAttr(const std::string &ann) : Attr(Annotate), Annotation(ann) {}
+ AnnotateAttr(llvm::StringRef ann) : Attr(Annotate), Annotation(ann) {}
const std::string& getAnnotation() const { return Annotation; }
@@ -217,7 +233,7 @@ public:
class AsmLabelAttr : public Attr {
std::string Label;
public:
- AsmLabelAttr(const std::string &L) : Attr(AsmLabel), Label(L) {}
+ AsmLabelAttr(llvm::StringRef L) : Attr(AsmLabel), Label(L) {}
const std::string& getLabel() const { return Label; }
@@ -235,7 +251,7 @@ DEF_SIMPLE_ATTR(AlwaysInline);
class AliasAttr : public Attr {
std::string Aliasee;
public:
- AliasAttr(const std::string &aliasee) : Attr(Alias), Aliasee(aliasee) {}
+ AliasAttr(llvm::StringRef aliasee) : Attr(Alias), Aliasee(aliasee) {}
const std::string& getAliasee() const { return Aliasee; }
@@ -304,11 +320,12 @@ DEF_SIMPLE_ATTR(Malloc);
DEF_SIMPLE_ATTR(NoReturn);
DEF_SIMPLE_ATTR(AnalyzerNoReturn);
DEF_SIMPLE_ATTR(Deprecated);
+DEF_SIMPLE_ATTR(Final);
class SectionAttr : public Attr {
std::string Name;
public:
- SectionAttr(const std::string &N) : Attr(Section), Name(N) {}
+ SectionAttr(llvm::StringRef N) : Attr(Section), Name(N) {}
const std::string& getName() const { return Name; }
@@ -367,11 +384,11 @@ class FormatAttr : public Attr {
std::string Type;
int formatIdx, firstArg;
public:
- FormatAttr(const std::string &type, int idx, int first) : Attr(Format),
+ FormatAttr(llvm::StringRef type, int idx, int first) : Attr(Format),
Type(type), formatIdx(idx), firstArg(first) {}
const std::string& getType() const { return Type; }
- void setType(const std::string &type) { Type = type; }
+ void setType(llvm::StringRef type) { Type = type; }
int getFormatIdx() const { return formatIdx; }
int getFirstArg() const { return firstArg; }
@@ -544,6 +561,11 @@ public:
DEF_SIMPLE_ATTR(CFReturnsRetained);
DEF_SIMPLE_ATTR(NSReturnsRetained);
+// C++0x member checking attributes.
+DEF_SIMPLE_ATTR(BaseCheck);
+DEF_SIMPLE_ATTR(Hiding);
+DEF_SIMPLE_ATTR(Override);
+
#undef DEF_SIMPLE_ATTR
} // end namespace clang
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index ac79a91..f794477 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -54,6 +54,32 @@ public:
TypeLoc getTypeLoc() const;
};
+/// UnresolvedSet - A set of unresolved declarations. This is needed
+/// in a lot of places, but isn't really worth breaking into its own
+/// header right now.
+class UnresolvedSet {
+ typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
+ DeclsTy Decls;
+
+public:
+ void addDecl(NamedDecl *D) {
+ Decls.push_back(D);
+ }
+
+ bool replace(const NamedDecl* Old, NamedDecl *New) {
+ for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I)
+ if (*I == Old)
+ return (*I = New, true);
+ return false;
+ }
+
+ unsigned size() const { return Decls.size(); }
+
+ typedef DeclsTy::const_iterator iterator;
+ iterator begin() const { return Decls.begin(); }
+ iterator end() const { return Decls.end(); }
+};
+
/// TranslationUnitDecl - The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
ASTContext &Ctx;
@@ -172,6 +198,26 @@ public:
/// \brief Determine whether this declaration has linkage.
bool hasLinkage() const;
+ /// \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;
+
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
NamedDecl *getUnderlyingDecl();
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 79f7663..e1f948f 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -503,12 +503,12 @@ private:
/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
/// doing something to a specific decl.
class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
- Decl *TheDecl;
+ const Decl *TheDecl;
SourceLocation Loc;
SourceManager &SM;
const char *Message;
public:
- PrettyStackTraceDecl(Decl *theDecl, SourceLocation L,
+ PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
SourceManager &sm, const char *Msg)
: TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index e5bf78c..990403e7 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -376,13 +376,13 @@ class CXXRecordDecl : public RecordDecl {
/// of this C++ class (but not its inherited conversion
/// functions). Each of the entries in this overload set is a
/// CXXConversionDecl.
- OverloadedFunctionDecl Conversions;
+ UnresolvedSet Conversions;
/// 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.
- OverloadedFunctionDecl VisibleConversions;
+ UnresolvedSet VisibleConversions;
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
@@ -400,7 +400,7 @@ class CXXRecordDecl : public RecordDecl {
const llvm::SmallPtrSet<CanQualType, 8> &TopConversionsTypeSet,
const llvm::SmallPtrSet<CanQualType, 8> &HiddenConversionTypes);
void collectConversionFunctions(
- llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet);
+ llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const;
protected:
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
@@ -581,22 +581,34 @@ public:
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
- OverloadedFunctionDecl *getConversionFunctions() {
+ UnresolvedSet *getConversionFunctions() {
assert((this->isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"getConversionFunctions() called on incomplete type");
return &Conversions;
}
- const OverloadedFunctionDecl *getConversionFunctions() const {
+ const UnresolvedSet *getConversionFunctions() const {
assert((this->isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"getConversionFunctions() called on incomplete type");
return &Conversions;
}
+ typedef UnresolvedSet::iterator conversion_iterator;
+ conversion_iterator conversion_begin() const { return Conversions.begin(); }
+ conversion_iterator conversion_end() const { return Conversions.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);
+ }
+
/// getVisibleConversionFunctions - get all conversion functions visible
/// in current class; including conversion function templates.
- OverloadedFunctionDecl *getVisibleConversionFunctions();
+ const UnresolvedSet *getVisibleConversionFunctions();
+
/// addVisibleConversionFunction - Add a new conversion function to the
/// list of visible conversion functions.
void addVisibleConversionFunction(CXXConversionDecl *ConvDecl);
@@ -1502,9 +1514,9 @@ class UsingDirectiveDecl : public NamedDecl {
SourceLocation IdentLoc;
/// NominatedNamespace - Namespace nominated by using-directive.
- NamespaceDecl *NominatedNamespace;
+ NamedDecl *NominatedNamespace;
- /// Enclosing context containing both using-directive and nomintated
+ /// Enclosing context containing both using-directive and nominated
/// namespace.
DeclContext *CommonAncestor;
@@ -1520,12 +1532,12 @@ class UsingDirectiveDecl : public NamedDecl {
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc,
- NamespaceDecl *Nominated,
+ NamedDecl *Nominated,
DeclContext *CommonAncestor)
: NamedDecl(Decl::UsingDirective, DC, L, getName()),
NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange),
Qualifier(Qualifier), IdentLoc(IdentLoc),
- NominatedNamespace(Nominated? Nominated->getOriginalNamespace() : 0),
+ NominatedNamespace(Nominated),
CommonAncestor(CommonAncestor) {
}
@@ -1538,8 +1550,13 @@ public:
/// name of the namespace.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
+ const NamedDecl *getNominatedNamespaceAsWritten() const {
+ return NominatedNamespace;
+ }
+
/// getNominatedNamespace - Returns namespace nominated by using-directive.
- NamespaceDecl *getNominatedNamespace() { return NominatedNamespace; }
+ NamespaceDecl *getNominatedNamespace();
const NamespaceDecl *getNominatedNamespace() const {
return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
@@ -1562,7 +1579,7 @@ public:
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc,
- NamespaceDecl *Nominated,
+ NamedDecl *Nominated,
DeclContext *CommonAncestor);
static bool classof(const Decl *D) {
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 14f6660..3ecc4bb 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -955,8 +955,7 @@ public:
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
- TemplateArgumentLoc *ArgInfos,
- unsigned NumArgInfos,
+ const TemplateArgumentListInfo &ArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl);
/// Get the list of template parameters
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index a30f6e8..676bd2c 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -25,6 +25,7 @@ namespace llvm {
namespace clang {
class CXXSpecialName;
class CXXOperatorIdName;
+ class CXXLiteralOperatorIdName;
class DeclarationNameExtra;
class IdentifierInfo;
class MultiKeywordSelector;
@@ -48,6 +49,7 @@ public:
CXXDestructorName,
CXXConversionFunctionName,
CXXOperatorName,
+ CXXLiteralOperatorName,
CXXUsingDirective
};
@@ -115,6 +117,12 @@ private:
return 0;
}
+ CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
+ if (getNameKind() == CXXLiteralOperatorName)
+ return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
+ return 0;
+ }
+
// Construct a declaration name from the name of a C++ constructor,
// destructor, or conversion function.
DeclarationName(CXXSpecialName *Name)
@@ -131,6 +139,12 @@ private:
Ptr |= StoredDeclarationNameExtra;
}
+ DeclarationName(CXXLiteralOperatorIdName *Name)
+ : Ptr(reinterpret_cast<uintptr_t>(Name)) {
+ assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
+ Ptr |= StoredDeclarationNameExtra;
+ }
+
/// Construct a declaration name from a raw pointer.
DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
@@ -201,7 +215,7 @@ public:
N.Ptr = reinterpret_cast<uintptr_t> (P);
return N;
}
-
+
static DeclarationName getFromOpaqueInteger(uintptr_t P) {
DeclarationName N;
N.Ptr = P;
@@ -218,6 +232,10 @@ public:
/// kind of overloaded operator.
OverloadedOperatorKind getCXXOverloadedOperator() const;
+ /// getCXXLiteralIdentifier - If this name is the name of a literal
+ /// operator, retrieve the identifier associated with it.
+ IdentifierInfo *getCXXLiteralIdentifier() const;
+
/// getObjCSelector - Get the Objective-C selector stored in this
/// declaration name.
Selector getObjCSelector() const;
@@ -293,7 +311,7 @@ public:
/// getIdentifier - Create a declaration name that is a simple
/// identifier.
- DeclarationName getIdentifier(IdentifierInfo *ID) {
+ DeclarationName getIdentifier(const IdentifierInfo *ID) {
return DeclarationName(ID);
}
@@ -324,6 +342,10 @@ public:
/// getCXXOperatorName - Get the name of the overloadable C++
/// operator corresponding to Op.
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
+
+ /// getCXXLiteralOperatorName - Get the name of the literal operator function
+ /// with II as the identifier.
+ DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
};
/// Insertion operator for diagnostics. This allows sending DeclarationName's
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index dfc5b13..7cf9aab 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -35,6 +35,7 @@ namespace clang {
class CXXOperatorCallExpr;
class CXXMemberCallExpr;
class TemplateArgumentLoc;
+ class TemplateArgumentListInfo;
/// Expr - This represents one expression. Note that Expr's are subclasses of
/// Stmt. This allows an expression to be transparently used any place a Stmt
@@ -366,6 +367,10 @@ struct ExplicitTemplateArgumentList {
const TemplateArgumentLoc *getTemplateArgs() const {
return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
}
+
+ void initializeFrom(const TemplateArgumentListInfo &List);
+ void copyInto(TemplateArgumentListInfo &List) const;
+ static std::size_t sizeFor(const TemplateArgumentListInfo &List);
};
/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
@@ -423,31 +428,24 @@ class DeclRefExpr : public Expr {
DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
NamedDecl *D, SourceLocation NameLoc,
- bool HasExplicitTemplateArgumentList,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *ExplicitTemplateArgs,
- unsigned NumExplicitTemplateArgs,
- SourceLocation RAngleLoc,
- QualType T, bool TD, bool VD);
+ const TemplateArgumentListInfo *TemplateArgs,
+ QualType T);
protected:
- // FIXME: Eventually, this constructor will go away and all subclasses
- // will have to provide the type- and value-dependent flags.
- DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
- Expr(SC, t), DecoratedD(d, 0), Loc(l) {}
+ /// \brief Computes the type- and value-dependence flags for this
+ /// declaration reference expression.
+ void computeDependence();
- DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l, bool TD,
- bool VD) :
- Expr(SC, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
+ DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
+ Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) {
+ computeDependence();
+ }
public:
- // FIXME: Eventually, this constructor will go away and all clients
- // will have to provide the type- and value-dependent flags.
DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) :
- Expr(DeclRefExprClass, t), DecoratedD(d, 0), Loc(l) {}
-
- DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l, bool TD, bool VD) :
- Expr(DeclRefExprClass, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
+ Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) {
+ computeDependence();
+ }
/// \brief Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty)
@@ -458,19 +456,8 @@ public:
SourceRange QualifierRange,
NamedDecl *D,
SourceLocation NameLoc,
- QualType T, bool TD, bool VD);
-
- static DeclRefExpr *Create(ASTContext &Context,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
- NamedDecl *D,
- SourceLocation NameLoc,
- bool HasExplicitTemplateArgumentList,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *ExplicitTemplateArgs,
- unsigned NumExplicitTemplateArgs,
- SourceLocation RAngleLoc,
- QualType T, bool TD, bool VD);
+ QualType T,
+ const TemplateArgumentListInfo *TemplateArgs = 0);
NamedDecl *getDecl() { return DecoratedD.getPointer(); }
const NamedDecl *getDecl() const { return DecoratedD.getPointer(); }
@@ -508,6 +495,13 @@ public:
bool hasExplicitTemplateArgumentList() const {
return DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag;
}
+
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ if (hasExplicitTemplateArgumentList())
+ getExplicitTemplateArgumentList()->copyInto(List);
+ }
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
@@ -546,8 +540,7 @@ public:
}
static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclRefExprClass ||
- T->getStmtClass() == CXXConditionDeclExprClass;
+ return T->getStmtClass() == DeclRefExprClass;
}
static bool classof(const DeclRefExpr *) { return true; }
@@ -1313,9 +1306,7 @@ class MemberExpr : public Expr {
MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l,
- bool has_explicit, SourceLocation langle,
- const TemplateArgumentLoc *targs, unsigned numtargs,
- SourceLocation rangle, QualType ty);
+ const TemplateArgumentListInfo *targs, QualType ty);
public:
MemberExpr(Expr *base, bool isarrow, NamedDecl *memberdecl, SourceLocation l,
@@ -1334,11 +1325,7 @@ public:
NestedNameSpecifier *qual, SourceRange qualrange,
NamedDecl *memberdecl,
SourceLocation l,
- bool has_explicit,
- SourceLocation langle,
- const TemplateArgumentLoc *targs,
- unsigned numtargs,
- SourceLocation rangle,
+ const TemplateArgumentListInfo *targs,
QualType ty);
void setBase(Expr *E) { Base = E; }
@@ -1378,10 +1365,17 @@ public:
/// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgumentList() {
+ bool hasExplicitTemplateArgumentList() const {
return HasExplicitTemplateArgumentList;
}
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ if (hasExplicitTemplateArgumentList())
+ getExplicitTemplateArgumentList()->copyInto(List);
+ }
+
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
@@ -1579,7 +1573,11 @@ public:
CK_FloatingToIntegral,
/// CK_FloatingCast - Casting between floating types of different size.
- CK_FloatingCast
+ CK_FloatingCast,
+
+ /// CK_MemberPointerToBoolean - Member pointer to boolean
+ CK_MemberPointerToBoolean
+
};
private:
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 9e6fd4f..23844ce 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -17,6 +17,7 @@
#include "clang/Basic/TypeTraits.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/TemplateBase.h"
namespace clang {
@@ -24,6 +25,7 @@ namespace clang {
class CXXDestructorDecl;
class CXXMethodDecl;
class CXXTemporary;
+ class TemplateArgumentListInfo;
//===--------------------------------------------------------------------===//
// C++ Expressions.
@@ -669,40 +671,6 @@ public:
virtual child_iterator child_end();
};
-/// CXXConditionDeclExpr - Condition declaration of a if/switch/while/for
-/// statement, e.g: "if (int x = f()) {...}".
-/// The main difference with DeclRefExpr is that CXXConditionDeclExpr owns the
-/// decl that it references.
-///
-class CXXConditionDeclExpr : public DeclRefExpr {
-public:
- CXXConditionDeclExpr(SourceLocation startLoc,
- SourceLocation eqLoc, VarDecl *var)
- : DeclRefExpr(CXXConditionDeclExprClass, var,
- var->getType().getNonReferenceType(), startLoc,
- var->getType()->isDependentType(),
- /*FIXME:integral constant?*/
- var->getType()->isDependentType()) {}
-
- SourceLocation getStartLoc() const { return getLocation(); }
-
- VarDecl *getVarDecl() { return cast<VarDecl>(getDecl()); }
- const VarDecl *getVarDecl() const { return cast<VarDecl>(getDecl()); }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(getStartLoc(), getVarDecl()->getInit()->getLocEnd());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConditionDeclExprClass;
- }
- static bool classof(const CXXConditionDeclExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
/// CXXNewExpr - A new expression for memory allocation and constructor calls,
/// e.g: "new CXXNewExpr(foo)".
class CXXNewExpr : public Expr {
@@ -975,52 +943,6 @@ public:
virtual child_iterator child_end();
};
-/// \brief Represents the name of a function that has not been
-/// resolved to any declaration.
-///
-/// Unresolved function names occur when a function name is
-/// encountered prior to an open parentheses ('(') in a C++ function
-/// call, and the function name itself did not resolve to a
-/// declaration. These function names can only be resolved when they
-/// form the postfix-expression of a function call, so that
-/// argument-dependent lookup finds declarations corresponding to
-/// these functions.
-
-/// @code
-/// template<typename T> void f(T x) {
-/// g(x); // g is an unresolved function name (that is also a dependent name)
-/// }
-/// @endcode
-class UnresolvedFunctionNameExpr : public Expr {
- /// The name that was present in the source
- DeclarationName Name;
-
- /// The location of this name in the source code
- SourceLocation Loc;
-
-public:
- UnresolvedFunctionNameExpr(DeclarationName N, QualType T, SourceLocation L)
- : Expr(UnresolvedFunctionNameExprClass, T, false, false), Name(N), Loc(L) { }
-
- /// \brief Retrieves the name that occurred in the source code.
- DeclarationName getName() const { return Name; }
-
- /// getLocation - Retrieves the location in the source code where
- /// the name occurred.
- SourceLocation getLocation() const { return Loc; }
-
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedFunctionNameExprClass;
- }
- static bool classof(const UnresolvedFunctionNameExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
/// UnaryTypeTraitExpr - A GCC or MS unary type trait, as used in the
/// implementation of TR1/C++0x type trait templates.
/// Example:
@@ -1063,21 +985,177 @@ 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 {
+ /// The results. These are undesugared, which is to say, they may
+ /// include UsingShadowDecls.
+ UnresolvedSet Results;
+
+ /// The name declared.
+ DeclarationName Name;
+
+ /// The qualifier given, if any.
+ NestedNameSpecifier *Qualifier;
+
+ /// The source range of the nested name specifier.
+ SourceRange QualifierRange;
+
+ /// The location of the name.
+ SourceLocation NameLoc;
+
+ /// True if these lookup results should be extended by
+ /// argument-dependent lookup if this is the operand of a function
+ /// call.
+ bool RequiresADL;
+
+ /// True if these lookup results are overloaded. This is pretty
+ /// 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;
+
+ UnresolvedLookupExpr(QualType T, bool Dependent,
+ 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)
+ {}
+
+public:
+ static UnresolvedLookupExpr *Create(ASTContext &C,
+ bool Dependent,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ bool ADL, bool Overloaded) {
+ return new(C) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
+ Dependent, Qualifier, QualifierRange,
+ Name, NameLoc, ADL, Overloaded, false);
+ }
+
+ static UnresolvedLookupExpr *Create(ASTContext &C,
+ bool Dependent,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ 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(NamedDecl * const *Begin,
+ NamedDecl * const *End,
+ const TemplateArgumentListInfo *Args);
+
+ void addDecl(NamedDecl *Decl) {
+ Results.addDecl(Decl);
+ }
+
+ typedef UnresolvedSet::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; }
+
+ /// 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; }
+
+ // Note that, inconsistently with the explicit-template-argument AST
+ // nodes, users are *forbidden* from calling these methods on objects
+ // without explicit template arguments.
+
+ /// Gets a reference to the explicit template argument list.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
+ }
+
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ getExplicitTemplateArgs().copyInto(List);
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return getExplicitTemplateArgs().LAngleLoc;
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return getExplicitTemplateArgs().RAngleLoc;
+ }
+
+ TemplateArgumentLoc const *getTemplateArgs() const {
+ return getExplicitTemplateArgs().getTemplateArgs();
+ }
+
+ unsigned getNumTemplateArgs() const {
+ return getExplicitTemplateArgs().NumTemplateArgs;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ SourceRange Range(NameLoc);
+ if (Qualifier) Range.setBegin(QualifierRange.getBegin());
+ if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
+ return Range;
+ }
+
+ virtual StmtIterator child_begin();
+ virtual StmtIterator child_end();
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnresolvedLookupExprClass;
+ }
+ static bool classof(const UnresolvedLookupExpr *) { return true; }
+};
+
/// \brief A qualified reference to a name whose declaration cannot
/// yet be resolved.
///
-/// UnresolvedDeclRefExpr is similar to eclRefExpr in that
+/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
/// it expresses a reference to a declaration such as
/// X<T>::value. The difference, however, is that an
-/// UnresolvedDeclRefExpr node is used only within C++ templates when
+/// DependentScopeDeclRefExpr node is used only within C++ templates when
/// the qualification (e.g., X<T>::) refers to a dependent type. In
/// this case, X<T>::value cannot resolve to a declaration because the
/// declaration will differ from on instantiation of X<T> to the
-/// next. Therefore, UnresolvedDeclRefExpr keeps track of the
+/// next. Therefore, DependentScopeDeclRefExpr keeps track of the
/// qualifier (X<T>::) and the name of the entity being referenced
/// ("value"). Such expressions will instantiate to a DeclRefExpr once the
/// declaration can be found.
-class UnresolvedDeclRefExpr : public Expr {
+class DependentScopeDeclRefExpr : public Expr {
/// The name of the entity we will be referencing.
DeclarationName Name;
@@ -1090,19 +1168,30 @@ class UnresolvedDeclRefExpr : public Expr {
/// \brief The nested-name-specifier that qualifies this unresolved
/// declaration name.
- NestedNameSpecifier *NNS;
+ NestedNameSpecifier *Qualifier;
- /// \brief Whether this expr is an address of (&) operand.
- /// FIXME: Stash this bit into NNS!
- bool IsAddressOfOperand;
+ /// \brief Whether the name includes explicit template arguments.
+ bool HasExplicitTemplateArgs;
+
+ DependentScopeDeclRefExpr(QualType T,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ bool HasExplicitTemplateArgs)
+ : Expr(DependentScopeDeclRefExprClass, T, true, true),
+ Name(Name), Loc(NameLoc),
+ QualifierRange(QualifierRange), Qualifier(Qualifier),
+ HasExplicitTemplateArgs(HasExplicitTemplateArgs)
+ {}
public:
- UnresolvedDeclRefExpr(DeclarationName N, QualType T, SourceLocation L,
- SourceRange R, NestedNameSpecifier *NNS,
- bool IsAddressOfOperand)
- : Expr(UnresolvedDeclRefExprClass, T, true, true),
- Name(N), Loc(L), QualifierRange(R), NNS(NNS),
- IsAddressOfOperand(IsAddressOfOperand) { }
+ static DependentScopeDeclRefExpr *Create(ASTContext &C,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ const TemplateArgumentListInfo *TemplateArgs = 0);
/// \brief Retrieve the name that this expression refers to.
DeclarationName getDeclName() const { return Name; }
@@ -1115,116 +1204,57 @@ public:
/// \brief Retrieve the nested-name-specifier that qualifies this
/// declaration.
- NestedNameSpecifier *getQualifier() const { return NNS; }
-
- /// \brief Retrieve whether this is an address of (&) operand.
-
- bool isAddressOfOperand() const { return IsAddressOfOperand; }
- virtual SourceRange getSourceRange() const {
- return SourceRange(QualifierRange.getBegin(), getLocation());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedDeclRefExprClass;
- }
- static bool classof(const UnresolvedDeclRefExpr *) { return true; }
-
- virtual StmtIterator child_begin();
- virtual StmtIterator child_end();
-};
-
-/// \brief An expression that refers to a C++ template-id, such as
-/// @c isa<FunctionDecl>.
-class TemplateIdRefExpr : public Expr {
- /// \brief If this template-id was qualified-id, e.g., @c std::sort<int>,
- /// this nested name specifier contains the @c std::.
- NestedNameSpecifier *Qualifier;
-
- /// \brief If this template-id was a qualified-id, e.g., @c std::sort<int>,
- /// this covers the source code range of the @c std::.
- SourceRange QualifierRange;
-
- /// \brief The actual template to which this template-id refers.
- TemplateName Template;
-
- /// \brief The source location of the template name.
- SourceLocation TemplateNameLoc;
-
- /// \brief The source location of the left angle bracket ('<');
- SourceLocation LAngleLoc;
-
- /// \brief The source location of the right angle bracket ('>');
- SourceLocation RAngleLoc;
-
- /// \brief The number of template arguments in TemplateArgs.
- unsigned NumTemplateArgs;
-
- TemplateIdRefExpr(QualType T,
- NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
- TemplateName Template, SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc);
-
- virtual void DoDestroy(ASTContext &Context);
-
-public:
- static TemplateIdRefExpr *
- Create(ASTContext &Context, QualType T,
- NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
- TemplateName Template, SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc, const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs, SourceLocation RAngleLoc);
-
- /// \brief Retrieve the nested name specifier used to qualify the name of
- /// this template-id, e.g., the "std::sort" in @c std::sort<int>, or NULL
- /// if this template-id was an unqualified-id.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
- /// \brief Retrieve the source range describing the nested name specifier
- /// used to qualified the name of this template-id, if the name was qualified.
- SourceRange getQualifierRange() const { return QualifierRange; }
+ /// Determines whether this lookup had explicit template arguments.
+ bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
- /// \brief Retrieve the name of the template referenced, e.g., "sort" in
- /// @c std::sort<int>;
- TemplateName getTemplateName() const { return Template; }
+ // Note that, inconsistently with the explicit-template-argument AST
+ // nodes, users are *forbidden* from calling these methods on objects
+ // without explicit template arguments.
- /// \brief Retrieve the location of the name of the template referenced, e.g.,
- /// the location of "sort" in @c std::sort<int>.
- SourceLocation getTemplateNameLoc() const { return TemplateNameLoc; }
+ /// Gets a reference to the explicit template argument list.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
+ }
- /// \brief Retrieve the location of the left angle bracket following the
- /// template name ('<').
- SourceLocation getLAngleLoc() const { return LAngleLoc; }
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ getExplicitTemplateArgs().copyInto(List);
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return getExplicitTemplateArgs().LAngleLoc;
+ }
- /// \brief Retrieve the template arguments provided as part of this
- /// template-id.
- const TemplateArgumentLoc *getTemplateArgs() const {
- return reinterpret_cast<const TemplateArgumentLoc *>(this + 1);
+ SourceLocation getRAngleLoc() const {
+ return getExplicitTemplateArgs().RAngleLoc;
}
- /// \brief Retrieve the number of template arguments provided as part of this
- /// template-id.
- unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
+ TemplateArgumentLoc const *getTemplateArgs() const {
+ return getExplicitTemplateArgs().getTemplateArgs();
+ }
- /// \brief Retrieve the location of the right angle bracket following the
- /// template arguments ('>').
- SourceLocation getRAngleLoc() const { return RAngleLoc; }
+ unsigned getNumTemplateArgs() const {
+ return getExplicitTemplateArgs().NumTemplateArgs;
+ }
virtual SourceRange getSourceRange() const {
- return SourceRange(Qualifier? QualifierRange.getBegin() : TemplateNameLoc,
- RAngleLoc);
+ SourceRange Range(QualifierRange.getBegin(), getLocation());
+ if (hasExplicitTemplateArgs())
+ Range.setEnd(getRAngleLoc());
+ return Range;
}
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
static bool classof(const Stmt *T) {
- return T->getStmtClass() == TemplateIdRefExprClass;
+ return T->getStmtClass() == DependentScopeDeclRefExprClass;
}
- static bool classof(const TemplateIdRefExpr *) { return true; }
+ static bool classof(const DependentScopeDeclRefExpr *) { return true; }
+
+ virtual StmtIterator child_begin();
+ virtual StmtIterator child_end();
};
class CXXExprWithTemporaries : public Expr {
@@ -1377,10 +1407,10 @@ public:
virtual child_iterator child_end();
};
-/// \brief Represents a C++ member access expression where the actual member
-/// referenced could not be resolved, e.g., because the base expression or the
-/// member name was dependent.
-class CXXUnresolvedMemberExpr : public Expr {
+/// \brief Represents a C++ member access expression where the actual
+/// member referenced could not be resolved because the base
+/// expression or the member name was dependent.
+class CXXDependentScopeMemberExpr : public Expr {
/// \brief The expression for the base pointer or class reference,
/// e.g., the \c x in x.f.
Stmt *Base;
@@ -1408,7 +1438,7 @@ class CXXUnresolvedMemberExpr : public Expr {
///
/// FIXME: This member, along with the Qualifier and QualifierRange, could
/// be stuck into a structure that is optionally allocated at the end of
- /// the CXXUnresolvedMemberExpr, to save space in the common case.
+ /// the CXXDependentScopeMemberExpr, to save space in the common case.
NamedDecl *FirstQualifierFoundInScope;
/// \brief The member to which this member expression refers, which
@@ -1431,11 +1461,11 @@ class CXXUnresolvedMemberExpr : public Expr {
/// \brief Retrieve the explicit template argument list that followed the
/// member template name, if any.
const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
- return const_cast<CXXUnresolvedMemberExpr *>(this)
+ return const_cast<CXXDependentScopeMemberExpr *>(this)
->getExplicitTemplateArgumentList();
}
- CXXUnresolvedMemberExpr(ASTContext &C,
+ CXXDependentScopeMemberExpr(ASTContext &C,
Expr *Base, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
@@ -1443,14 +1473,10 @@ class CXXUnresolvedMemberExpr : public Expr {
NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member,
SourceLocation MemberLoc,
- bool HasExplicitTemplateArgs,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc);
+ const TemplateArgumentListInfo *TemplateArgs);
public:
- CXXUnresolvedMemberExpr(ASTContext &C,
+ CXXDependentScopeMemberExpr(ASTContext &C,
Expr *Base, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
@@ -1458,14 +1484,14 @@ public:
NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member,
SourceLocation MemberLoc)
- : Expr(CXXUnresolvedMemberExprClass, C.DependentTy, true, true),
+ : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
Base(Base), IsArrow(IsArrow), HasExplicitTemplateArgumentList(false),
OperatorLoc(OperatorLoc),
Qualifier(Qualifier), QualifierRange(QualifierRange),
FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Member(Member), MemberLoc(MemberLoc) { }
- static CXXUnresolvedMemberExpr *
+ static CXXDependentScopeMemberExpr *
Create(ASTContext &C,
Expr *Base, bool IsArrow,
SourceLocation OperatorLoc,
@@ -1474,11 +1500,7 @@ public:
NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member,
SourceLocation MemberLoc,
- bool HasExplicitTemplateArgs,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc);
+ const TemplateArgumentListInfo *TemplateArgs);
/// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
@@ -1529,10 +1551,17 @@ public:
/// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgumentList() {
+ bool hasExplicitTemplateArgumentList() const {
return HasExplicitTemplateArgumentList;
}
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ if (hasExplicitTemplateArgumentList())
+ getExplicitTemplateArgumentList()->copyInto(List);
+ }
+
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
@@ -1579,9 +1608,182 @@ public:
}
static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXUnresolvedMemberExprClass;
+ return T->getStmtClass() == CXXDependentScopeMemberExprClass;
+ }
+ static bool classof(const CXXDependentScopeMemberExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// \brief Represents a C++ member access expression for which lookup
+/// produced a set of overloaded functions. These are replaced with
+/// MemberExprs in the final AST.
+class UnresolvedMemberExpr : public Expr {
+ /// The results. These are undesugared, which is to say, they may
+ /// include UsingShadowDecls.
+ UnresolvedSet Results;
+
+ /// \brief The expression for the base pointer or class reference,
+ /// e.g., the \c x in x.f.
+ Stmt *Base;
+
+ /// \brief Whether this member expression used the '->' operator or
+ /// the '.' operator.
+ bool IsArrow : 1;
+
+ /// \brief Whether the lookup results contain an unresolved using
+ /// declaration.
+ bool HasUnresolvedUsing : 1;
+
+ /// \brief Whether this member expression has explicitly-specified template
+ /// arguments.
+ bool HasExplicitTemplateArgs : 1;
+
+ /// \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, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Member,
+ SourceLocation MemberLoc,
+ const TemplateArgumentListInfo *TemplateArgs);
+
+public:
+ static UnresolvedMemberExpr *
+ Create(ASTContext &C, bool Dependent, bool HasUnresolvedUsing,
+ Expr *Base, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Member,
+ 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 UnresolvedSet::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 Retrieve the base object of this member expressions,
+ /// e.g., the \c x in \c x.m.
+ Expr *getBase() { return cast<Expr>(Base); }
+ void setBase(Expr *E) { Base = E; }
+
+ /// \brief Determine whether this member expression used the '->'
+ /// operator; otherwise, it used the '.' operator.
+ bool isArrow() const { return IsArrow; }
+ void setArrow(bool A) { IsArrow = A; }
+
+ /// \brief Retrieve the location of the '->' or '.' operator.
+ SourceLocation getOperatorLoc() const { return OperatorLoc; }
+ void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
+
+ /// \brief Retrieve the nested-name-specifier that qualifies the member
+ /// name.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// \brief Retrieve the source range covering the nested-name-specifier
+ /// that qualifies the member name.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief Retrieve the name of the member that this expression
+ /// refers to.
+ DeclarationName getMemberName() const { return MemberName; }
+ void setMemberName(DeclarationName N) { MemberName = 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; }
+
+ /// \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 Copies the template arguments into the given structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ getExplicitTemplateArgs()->copyInto(List);
+ }
+
+ /// \brief Retrieve the location of the left angle bracket following
+ /// the member name ('<').
+ SourceLocation getLAngleLoc() const {
+ return getExplicitTemplateArgs()->LAngleLoc;
+ }
+
+ /// \brief Retrieve the template arguments provided as part of this
+ /// template-id.
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return getExplicitTemplateArgs()->getTemplateArgs();
+ }
+
+ /// \brief Retrieve the number of template arguments provided as
+ /// part of this template-id.
+ unsigned getNumTemplateArgs() const {
+ return getExplicitTemplateArgs()->NumTemplateArgs;
+ }
+
+ /// \brief Retrieve the location of the right angle bracket
+ /// following the template arguments ('>').
+ SourceLocation getRAngleLoc() const {
+ return getExplicitTemplateArgs()->RAngleLoc;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ SourceRange Range = Base->getSourceRange();
+ if (hasExplicitTemplateArgs())
+ Range.setEnd(getRAngleLoc());
+ else
+ Range.setEnd(MemberLoc);
+ return Range;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnresolvedMemberExprClass;
}
- static bool classof(const CXXUnresolvedMemberExpr *) { return true; }
+ static bool classof(const UnresolvedMemberExpr *) { return true; }
// Iterators
virtual child_iterator child_begin();
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 9b1c640..5d2973e 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -47,6 +47,59 @@ class ASTRecordLayout {
// FieldCount - Number of fields.
unsigned FieldCount;
+public:
+ /// PrimaryBaseInfo - Contains info about a primary base.
+ struct PrimaryBaseInfo {
+ PrimaryBaseInfo() {}
+
+ PrimaryBaseInfo(const CXXRecordDecl *Base, bool IsVirtual)
+ : Value(Base, IsVirtual) {}
+
+ /// Value - Points to the primary base. The single-bit value
+ /// will be non-zero when the primary base is virtual.
+ llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Value;
+
+ /// getBase - Returns the primary base.
+ const CXXRecordDecl *getBase() const { return Value.getPointer(); }
+
+ /// isVirtual - Returns whether the primary base is virtual or not.
+ bool isVirtual() const { return Value.getInt(); }
+
+ friend bool operator==(const PrimaryBaseInfo &X, const PrimaryBaseInfo &Y) {
+ return X.Value == Y.Value;
+ }
+ };
+
+ /// primary_base_info_iterator - An iterator for iterating the primary base
+ /// class chain.
+ class primary_base_info_iterator {
+ /// Current - The current base class info.
+ PrimaryBaseInfo Current;
+
+ public:
+ primary_base_info_iterator() {}
+ primary_base_info_iterator(PrimaryBaseInfo Info) : Current(Info) {}
+
+ const PrimaryBaseInfo &operator*() const { return Current; }
+
+ primary_base_info_iterator& operator++() {
+ const CXXRecordDecl *RD = Current.getBase();
+ Current = RD->getASTContext().getASTRecordLayout(RD).getPrimaryBaseInfo();
+ return *this;
+ }
+
+ friend bool operator==(const primary_base_info_iterator &X,
+ const primary_base_info_iterator &Y) {
+ return X.Current == Y.Current;
+ }
+ friend bool operator!=(const primary_base_info_iterator &X,
+ const primary_base_info_iterator &Y) {
+ return !(X == Y);
+ }
+ };
+
+private:
+ /// CXXRecordLayoutInfo - Contains C++ specific layout information.
struct CXXRecordLayoutInfo {
/// NonVirtualSize - The non-virtual size (in bits) of an object, which is
/// the size of the object without virtual bases.
@@ -56,11 +109,9 @@ class ASTRecordLayout {
/// which is the alignment of the object without virtual bases.
uint64_t NonVirtualAlign;
- /// PrimaryBase - The primary base for our vtable.
- const CXXRecordDecl *PrimaryBase;
- /// PrimaryBase - Wether or not the primary base was a virtual base.
- bool PrimaryBaseWasVirtual;
-
+ /// PrimaryBase - The primary base info for this record.
+ PrimaryBaseInfo PrimaryBase;
+
/// BaseOffsets - Contains a map from base classes to their offset.
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets;
@@ -68,6 +119,13 @@ class ASTRecordLayout {
/// VBaseOffsets - Contains a map from vbase classes to their offset.
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
llvm::DenseMap<const CXXRecordDecl *, uint64_t> VBaseOffsets;
+
+ /// KeyFunction - The key function, according to the Itanium C++ ABI,
+ /// section 5.2.3:
+ ///
+ /// ...the first non-pure virtual function that is not inline at the point
+ /// of class definition.
+ const CXXMethodDecl *KeyFunction;
};
/// CXXInfo - If the record layout is for a C++ record, this will have
@@ -92,11 +150,12 @@ class ASTRecordLayout {
ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
uint64_t nonvirtualsize, unsigned nonvirtualalign,
- const CXXRecordDecl *PB, bool PBVirtual,
+ const PrimaryBaseInfo &PrimaryBase,
const std::pair<const CXXRecordDecl *, uint64_t> *bases,
unsigned numbases,
const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
- unsigned numvbases)
+ unsigned numvbases,
+ const CXXMethodDecl *KeyFunction)
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
if (FieldCount > 0) {
@@ -105,14 +164,14 @@ class ASTRecordLayout {
FieldOffsets[i] = fieldoffsets[i];
}
- CXXInfo->PrimaryBase = PB;
- CXXInfo->PrimaryBaseWasVirtual = PBVirtual;
+ CXXInfo->PrimaryBase = PrimaryBase;
CXXInfo->NonVirtualSize = nonvirtualsize;
CXXInfo->NonVirtualAlign = nonvirtualalign;
for (unsigned i = 0; i != numbases; ++i)
CXXInfo->BaseOffsets[bases[i].first] = bases[i].second;
for (unsigned i = 0; i != numvbases; ++i)
CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second;
+ CXXInfo->KeyFunction = KeyFunction;
}
~ASTRecordLayout() {
@@ -162,17 +221,21 @@ public:
return CXXInfo->NonVirtualAlign;
}
- /// getPrimaryBase - Get the primary base.
- const CXXRecordDecl *getPrimaryBase() const {
+ /// getPrimaryBaseInfo - Get the primary base info.
+ const PrimaryBaseInfo &getPrimaryBaseInfo() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->PrimaryBase;
}
- /// getPrimaryBaseWasVirtual - Indicates if the primary base was virtual.
- bool getPrimaryBaseWasVirtual() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->PrimaryBaseWasVirtual;
+ // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+ const CXXRecordDecl *getPrimaryBase() const {
+ return getPrimaryBaseInfo().getBase();
+ }
+
+ // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+ bool getPrimaryBaseWasVirtual() const {
+ return getPrimaryBaseInfo().isVirtual();
}
/// getBaseClassOffset - Get the offset, in bits, for the given base class.
@@ -190,6 +253,25 @@ public:
return CXXInfo->VBaseOffsets[VBase];
}
+
+ /// getKeyFunction - Get the key function.
+ const CXXMethodDecl *getKeyFunction() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return CXXInfo->KeyFunction;
+ }
+
+ primary_base_info_iterator primary_base_begin() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return primary_base_info_iterator(getPrimaryBaseInfo());
+ }
+
+ primary_base_info_iterator primary_base_end() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return primary_base_info_iterator();
+ }
};
} // end namespace clang
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 8679323..01f4b29 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_REDECLARABLE_H
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Casting.h"
#include <iterator>
namespace clang {
@@ -92,6 +93,11 @@ public:
}
/// \brief Returns the most recent (re)declaration of this declaration.
+ decl_type *getMostRecentDeclaration() {
+ return getFirstDeclaration()->RedeclLink.getNext();
+ }
+
+ /// \brief Returns the most recent (re)declaration of this declaration.
const decl_type *getMostRecentDeclaration() const {
return getFirstDeclaration()->RedeclLink.getNext();
}
@@ -102,8 +108,11 @@ public:
decl_type *First;
if (PrevDecl) {
- // Point to previous.
- RedeclLink = PreviousDeclLink(PrevDecl);
+ // Point to previous. Make sure that this is actually the most recent
+ // redeclaration, or we can build invalid chains. If the most recent
+ // redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
+ RedeclLink = PreviousDeclLink(llvm::cast<decl_type>(
+ PrevDecl->getMostRecentDeclaration()));
First = PrevDecl->getFirstDeclaration();
assert(First->RedeclLink.NextIsLatest() && "Expected first");
} else {
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 411f215e..d6f6a83 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -171,6 +171,14 @@ public:
}
virtual ~Stmt() {}
+#ifndef NDEBUG
+ /// \brief True if this statement's refcount is in a valid state.
+ /// Should be used only in assertions.
+ bool isRetained() const {
+ return (RefCount >= 1);
+ }
+#endif
+
/// \brief Destroy the current statement and its children.
void Destroy(ASTContext &Ctx) {
assert(RefCount >= 1);
@@ -203,7 +211,7 @@ public:
// global temp stats (until we have a per-module visitor)
static void addStmtClass(const StmtClass s);
- static bool CollectingStats(bool enable=false);
+ static bool CollectingStats(bool Enable = false);
static void PrintStats();
/// dump - This does a local dump of the specified AST fragment. It dumps the
@@ -604,22 +612,36 @@ public:
class IfStmt : public Stmt {
enum { COND, THEN, ELSE, END_EXPR };
Stmt* SubExprs[END_EXPR];
+
+ /// \brief If non-NULL, the declaration in the "if" statement.
+ VarDecl *Var;
+
SourceLocation IfLoc;
SourceLocation ElseLoc;
+
public:
- IfStmt(SourceLocation IL, Expr *cond, Stmt *then,
+ IfStmt(SourceLocation IL, VarDecl *Var, Expr *cond, Stmt *then,
SourceLocation EL = SourceLocation(), Stmt *elsev = 0)
- : Stmt(IfStmtClass) {
+ : Stmt(IfStmtClass), Var(Var), IfLoc(IL), ElseLoc(EL) {
SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
SubExprs[THEN] = then;
SubExprs[ELSE] = elsev;
- IfLoc = IL;
- ElseLoc = EL;
}
/// \brief Build an empty if/then/else statement
explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
+ /// \brief Retrieve the variable declared in this "if" statement, if any.
+ ///
+ /// In the following example, "x" is the condition variable.
+ /// \code
+ /// if (int x = foo()) {
+ /// printf("x is %d", x);
+ /// }
+ /// \endcode
+ VarDecl *getConditionVariable() const { return Var; }
+ void setConditionVariable(VarDecl *V) { Var = V; }
+
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
const Stmt *getThen() const { return SubExprs[THEN]; }
@@ -658,6 +680,7 @@ public:
class SwitchStmt : public Stmt {
enum { COND, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR];
+ VarDecl *Var;
// This points to a linked list of case and default statements.
SwitchCase *FirstCase;
SourceLocation SwitchLoc;
@@ -666,14 +689,28 @@ protected:
virtual void DoDestroy(ASTContext &Ctx);
public:
- SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[BODY] = NULL;
- }
+ SwitchStmt(VarDecl *Var, Expr *cond)
+ : Stmt(SwitchStmtClass), Var(Var), FirstCase(0)
+ {
+ SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+ SubExprs[BODY] = NULL;
+ }
/// \brief Build a empty switch statement.
explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
+ /// \brief Retrieve the variable declared in this "switch" statement, if any.
+ ///
+ /// In the following example, "x" is the condition variable.
+ /// \code
+ /// switch (int x = foo()) {
+ /// case 0: break;
+ /// // ...
+ /// }
+ /// \endcode
+ VarDecl *getConditionVariable() const { return Var; }
+ void setConditionVariable(VarDecl *V) { Var = V; }
+
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
const Stmt *getBody() const { return SubExprs[BODY]; }
const SwitchCase *getSwitchCaseList() const { return FirstCase; }
@@ -721,10 +758,13 @@ public:
///
class WhileStmt : public Stmt {
enum { COND, BODY, END_EXPR };
+ VarDecl *Var;
Stmt* SubExprs[END_EXPR];
SourceLocation WhileLoc;
public:
- WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
+ WhileStmt(VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL)
+ : Stmt(WhileStmtClass), Var(Var)
+ {
SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
SubExprs[BODY] = body;
WhileLoc = WL;
@@ -733,6 +773,17 @@ public:
/// \brief Build an empty while statement.
explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
+ /// \brief Retrieve the variable declared in this "while" statement, if any.
+ ///
+ /// In the following example, "x" is the condition variable.
+ /// \code
+ /// while (int x = random()) {
+ /// // ...
+ /// }
+ /// \endcode
+ VarDecl *getConditionVariable() const { return Var; }
+ void setConditionVariable(VarDecl *V) { Var = V; }
+
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
@@ -812,26 +863,38 @@ public:
class ForStmt : public Stmt {
enum { INIT, COND, INC, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
+ VarDecl *CondVar;
SourceLocation ForLoc;
SourceLocation LParenLoc, RParenLoc;
public:
- ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL,
- SourceLocation LP, SourceLocation RP)
- : Stmt(ForStmtClass) {
+ ForStmt(Stmt *Init, Expr *Cond, VarDecl *CondVar, Expr *Inc, Stmt *Body,
+ SourceLocation FL, SourceLocation LP, SourceLocation RP)
+ : Stmt(ForStmtClass), CondVar(CondVar), ForLoc(FL), LParenLoc(LP),
+ RParenLoc(RP)
+ {
SubExprs[INIT] = Init;
SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
SubExprs[BODY] = Body;
- ForLoc = FL;
- LParenLoc = LP;
- RParenLoc = RP;
}
/// \brief Build an empty for statement.
explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
Stmt *getInit() { return SubExprs[INIT]; }
+
+ /// \brief Retrieve the variable declared in this "for" statement, if any.
+ ///
+ /// In the following example, "y" is the condition variable.
+ /// \code
+ /// for (int x = random(); int y = mangle(x); ++x) {
+ /// // ...
+ /// }
+ /// \endcode
+ VarDecl *getConditionVariable() const { return CondVar; }
+ void setConditionVariable(VarDecl *V) { CondVar = V; }
+
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
Stmt *getBody() { return SubExprs[BODY]; }
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 28fe348..64eea24 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -42,9 +42,9 @@ public:
}
SourceLocation getCatchLoc() const { return CatchLoc; }
- VarDecl *getExceptionDecl() { return ExceptionDecl; }
- QualType getCaughtType();
- Stmt *getHandlerBlock() { return HandlerBlock; }
+ VarDecl *getExceptionDecl() const { return ExceptionDecl; }
+ QualType getCaughtType() const;
+ Stmt *getHandlerBlock() const { return HandlerBlock; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXCatchStmtClass;
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index 034029a..7102336 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -121,20 +121,19 @@ EXPR(CXXThisExpr , Expr)
EXPR(CXXThrowExpr , Expr)
EXPR(CXXDefaultArgExpr , Expr)
EXPR(CXXZeroInitValueExpr , Expr)
-EXPR(CXXConditionDeclExpr , DeclRefExpr)
EXPR(CXXNewExpr , Expr)
EXPR(CXXDeleteExpr , Expr)
EXPR(CXXPseudoDestructorExpr, Expr)
-EXPR(UnresolvedFunctionNameExpr , Expr)
+EXPR(UnresolvedLookupExpr , Expr)
EXPR(UnaryTypeTraitExpr , Expr)
-EXPR(UnresolvedDeclRefExpr , Expr)
-EXPR(TemplateIdRefExpr , Expr)
+EXPR(DependentScopeDeclRefExpr , Expr)
EXPR(CXXConstructExpr , Expr)
EXPR(CXXBindTemporaryExpr , Expr)
EXPR(CXXExprWithTemporaries , Expr)
EXPR(CXXTemporaryObjectExpr , CXXConstructExpr)
EXPR(CXXUnresolvedConstructExpr, Expr)
-EXPR(CXXUnresolvedMemberExpr, Expr)
+EXPR(CXXDependentScopeMemberExpr, Expr)
+EXPR(UnresolvedMemberExpr , Expr)
// Obj-C Expressions.
EXPR(ObjCStringLiteral , Expr)
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 6db0958..b46b3dc 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_AST_TEMPLATEBASE_H
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
#include "clang/AST/Type.h"
#include "clang/AST/TemplateName.h"
@@ -437,6 +438,41 @@ public:
}
};
+/// A convenient class for passing around template argument
+/// information. Designed to be passed by reference.
+class TemplateArgumentListInfo {
+ llvm::SmallVector<TemplateArgumentLoc, 8> Arguments;
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
+
+public:
+ TemplateArgumentListInfo() {}
+
+ TemplateArgumentListInfo(SourceLocation LAngleLoc,
+ SourceLocation RAngleLoc)
+ : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
+
+ SourceLocation getLAngleLoc() const { return LAngleLoc; }
+ SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
+ void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
+ void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
+
+ unsigned size() const { return Arguments.size(); }
+
+ const TemplateArgumentLoc *getArgumentArray() const {
+ return Arguments.data();
+ }
+
+ const TemplateArgumentLoc &operator[](unsigned I) const {
+ return Arguments[I];
+ }
+
+ void addArgument(const TemplateArgumentLoc &Loc) {
+ Arguments.push_back(Loc);
+ }
+};
+
}
#endif
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index c28bafe..349487f 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -82,6 +82,7 @@ namespace clang {
class StmtIteratorBase;
class TemplateArgument;
class TemplateArgumentLoc;
+ class TemplateArgumentListInfo;
class QualifiedNameType;
struct PrintingPolicy;
@@ -859,6 +860,7 @@ public:
bool isObjCQualifiedClassType() const; // Class<foo>
bool isObjCIdType() const; // id
bool isObjCClassType() const; // Class
+ bool isObjCSelType() const; // Class
bool isObjCBuiltinType() const; // 'id' or 'Class'
bool isTemplateTypeParmType() const; // C++ template type parameter
bool isNullPtrType() const; // C++0x nullptr_t
@@ -1000,7 +1002,8 @@ public:
UndeducedAuto, // In C++0x, this represents the type of an auto variable
// that has not been deduced yet.
ObjCId, // This represents the ObjC 'id' type.
- ObjCClass // This represents the ObjC 'Class' type.
+ ObjCClass, // This represents the ObjC 'Class' type.
+ ObjCSel // This represents the ObjC 'SEL' type.
};
private:
Kind TypeKind;
@@ -1457,21 +1460,27 @@ public:
/// DependentSizedArrayType - This type represents an array type in
/// C++ whose size is a value-dependent expression. For example:
-/// @code
+///
+/// \code
/// template<typename T, int Size>
/// class array {
/// T data[Size];
/// };
-/// @endcode
+/// \endcode
+///
/// For these types, we won't actually know what the array bound is
/// until template instantiation occurs, at which point this will
/// become either a ConstantArrayType or a VariableArrayType.
class DependentSizedArrayType : public ArrayType {
ASTContext &Context;
- /// SizeExpr - An assignment expression that will instantiate to the
+ /// \brief An assignment expression that will instantiate to the
/// size of the array.
+ ///
+ /// The expression itself might be NULL, in which case the array
+ /// type will have its size deduced from an initializer.
Stmt *SizeExpr;
+
/// Brackets - The left and right array brackets.
SourceRange Brackets;
@@ -2272,6 +2281,8 @@ public:
static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
unsigned NumArgs);
+ static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &);
+
/// \brief Print a template argument list, including the '<' and '>'
/// enclosing the template arguments.
static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
@@ -2282,6 +2293,9 @@ public:
unsigned NumArgs,
const PrintingPolicy &Policy);
+ static std::string PrintTemplateArgumentList(const TemplateArgumentListInfo &,
+ const PrintingPolicy &Policy);
+
typedef const TemplateArgument * iterator;
iterator begin() const { return getArgs(); }
@@ -2534,6 +2548,7 @@ public:
return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
!Protocols.size();
}
+
/// isObjCQualifiedIdType - true for "id <p>".
bool isObjCQualifiedIdType() const {
return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
@@ -2881,8 +2896,13 @@ inline bool Type::isObjCClassType() const {
return OPT->isObjCClassType();
return false;
}
+inline bool Type::isObjCSelType() const {
+ if (const PointerType *OPT = getAs<PointerType>())
+ return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
+ return false;
+}
inline bool Type::isObjCBuiltinType() const {
- return isObjCIdType() || isObjCClassType();
+ return isObjCIdType() || isObjCClassType() || isObjCSelType();
}
inline bool Type::isTemplateTypeParmType() const {
return isa<TemplateTypeParmType>(CanonicalType);
OpenPOWER on IntegriCloud