summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/ExprCXX.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/ExprCXX.h')
-rw-r--r--include/clang/AST/ExprCXX.h126
1 files changed, 87 insertions, 39 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 23844ce..00ea202 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -527,6 +527,7 @@ public:
const_arg_iterator arg_begin() const { return Args; }
const_arg_iterator arg_end() const { return Args + NumArgs; }
+ Expr **getArgs() const { return reinterpret_cast<Expr **>(Args); }
unsigned getNumArgs() const { return NumArgs; }
/// getArg - Return the specified argument.
@@ -1410,18 +1411,26 @@ public:
/// \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.
+///
+/// Like UnresolvedMemberExprs, these can be either implicit or
+/// explicit accesses. It is only possible to get one of these with
+/// an implicit access if a qualifier is provided.
class CXXDependentScopeMemberExpr : public Expr {
/// \brief The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f.
+ /// e.g., the \c x in x.f. Can be null in implicit accesses.
Stmt *Base;
+ /// \brief The type of the base expression. Never null, even for
+ /// implicit accesses.
+ QualType BaseType;
+
/// \brief Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
/// \brief Whether this member expression has explicitly-specified template
/// arguments.
- bool HasExplicitTemplateArgumentList : 1;
+ bool HasExplicitTemplateArgs : 1;
/// \brief The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
@@ -1452,9 +1461,7 @@ class CXXDependentScopeMemberExpr : public Expr {
/// \brief Retrieve the explicit template argument list that followed the
/// member template name, if any.
ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
- if (!HasExplicitTemplateArgumentList)
- return 0;
-
+ assert(HasExplicitTemplateArgs);
return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
}
@@ -1466,7 +1473,7 @@ class CXXDependentScopeMemberExpr : public Expr {
}
CXXDependentScopeMemberExpr(ASTContext &C,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -1477,7 +1484,8 @@ class CXXDependentScopeMemberExpr : public Expr {
public:
CXXDependentScopeMemberExpr(ASTContext &C,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType,
+ bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -1485,15 +1493,15 @@ public:
DeclarationName Member,
SourceLocation MemberLoc)
: Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
- Base(Base), IsArrow(IsArrow), HasExplicitTemplateArgumentList(false),
- OperatorLoc(OperatorLoc),
+ Base(Base), BaseType(BaseType), IsArrow(IsArrow),
+ HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc),
Qualifier(Qualifier), QualifierRange(QualifierRange),
FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Member(Member), MemberLoc(MemberLoc) { }
static CXXDependentScopeMemberExpr *
Create(ASTContext &C,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -1502,11 +1510,21 @@ public:
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs);
+ /// \brief True if this is an implicit access, i.e. one in which the
+ /// member being accessed was not written in the source. The source
+ /// location of the operator is invalid in this case.
+ bool isImplicitAccess() const { return Base == 0; }
+
/// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
- Expr *getBase() { return cast<Expr>(Base); }
+ Expr *getBase() const {
+ assert(!isImplicitAccess());
+ return cast<Expr>(Base);
+ }
void setBase(Expr *E) { Base = E; }
+ QualType getBaseType() const { return BaseType; }
+
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
@@ -1551,60 +1569,59 @@ public:
/// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgumentList() const {
- return HasExplicitTemplateArgumentList;
+ bool hasExplicitTemplateArgs() const {
+ return HasExplicitTemplateArgs;
}
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgumentList())
- getExplicitTemplateArgumentList()->copyInto(List);
+ assert(HasExplicitTemplateArgs);
+ getExplicitTemplateArgumentList()->copyInto(List);
}
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
- if (!HasExplicitTemplateArgumentList)
- return SourceLocation();
-
+ assert(HasExplicitTemplateArgs);
return getExplicitTemplateArgumentList()->LAngleLoc;
}
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
- if (!HasExplicitTemplateArgumentList)
- return 0;
-
+ assert(HasExplicitTemplateArgs);
return getExplicitTemplateArgumentList()->getTemplateArgs();
}
/// \brief Retrieve the number of template arguments provided as part of this
/// template-id.
unsigned getNumTemplateArgs() const {
- if (!HasExplicitTemplateArgumentList)
- return 0;
-
+ assert(HasExplicitTemplateArgs);
return getExplicitTemplateArgumentList()->NumTemplateArgs;
}
/// \brief Retrieve the location of the right angle bracket following the
/// template arguments ('>').
SourceLocation getRAngleLoc() const {
- if (!HasExplicitTemplateArgumentList)
- return SourceLocation();
-
+ assert(HasExplicitTemplateArgs);
return getExplicitTemplateArgumentList()->RAngleLoc;
}
virtual SourceRange getSourceRange() const {
- if (HasExplicitTemplateArgumentList)
- return SourceRange(Base->getSourceRange().getBegin(),
- getRAngleLoc());
+ SourceRange Range;
+ if (!isImplicitAccess())
+ Range.setBegin(Base->getSourceRange().getBegin());
+ else if (getQualifier())
+ Range.setBegin(getQualifierRange().getBegin());
+ else
+ Range.setBegin(MemberLoc);
- return SourceRange(Base->getSourceRange().getBegin(),
- MemberLoc);
+ if (hasExplicitTemplateArgs())
+ Range.setEnd(getRAngleLoc());
+ else
+ Range.setEnd(MemberLoc);
+ return Range;
}
static bool classof(const Stmt *T) {
@@ -1618,17 +1635,31 @@ public:
};
/// \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.
+/// produced a set of overloaded functions.
+///
+/// The member access may be explicit or implicit:
+/// struct A {
+/// int a, b;
+/// int explicitAccess() { return this->a + this->A::b; }
+/// int implicitAccess() { return a + A::b; }
+/// };
+///
+/// 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 Results;
/// \brief The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f.
+ /// 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 Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
@@ -1672,7 +1703,7 @@ class UnresolvedMemberExpr : public Expr {
UnresolvedMemberExpr(QualType T, bool Dependent,
bool HasUnresolvedUsing,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -1683,7 +1714,7 @@ class UnresolvedMemberExpr : public Expr {
public:
static UnresolvedMemberExpr *
Create(ASTContext &C, bool Dependent, bool HasUnresolvedUsing,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -1704,11 +1735,21 @@ public:
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.
+ bool isImplicitAccess() const { return Base == 0; }
+
/// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
- Expr *getBase() { return cast<Expr>(Base); }
+ Expr *getBase() {
+ assert(!isImplicitAccess());
+ return cast<Expr>(Base);
+ }
void setBase(Expr *E) { Base = E; }
+ QualType getBaseType() const { return BaseType; }
+
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
@@ -1772,7 +1813,14 @@ public:
}
virtual SourceRange getSourceRange() const {
- SourceRange Range = Base->getSourceRange();
+ SourceRange Range;
+ if (!isImplicitAccess())
+ Range.setBegin(Base->getSourceRange().getBegin());
+ else if (getQualifier())
+ Range.setBegin(getQualifierRange().getBegin());
+ else
+ Range.setBegin(MemberLoc);
+
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());
else
OpenPOWER on IntegriCloud