aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Expr.cpp58
-rw-r--r--lib/AST/ExprCXX.cpp39
2 files changed, 60 insertions, 37 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 930457c249..99ce611394 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -943,6 +943,28 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
return E;
}
+SourceRange MemberExpr::getSourceRange() const {
+ SourceLocation StartLoc;
+ if (isImplicitAccess()) {
+ if (hasQualifier())
+ StartLoc = getQualifierLoc().getBeginLoc();
+ else
+ StartLoc = MemberLoc;
+ } else {
+ // FIXME: We don't want this to happen. Rather, we should be able to
+ // detect all kinds of implicit accesses more cleanly.
+ StartLoc = getBase()->getLocStart();
+ if (StartLoc.isInvalid())
+ StartLoc = MemberLoc;
+ }
+
+ SourceLocation EndLoc =
+ HasExplicitTemplateArgumentList? getRAngleLoc()
+ : getMemberNameInfo().getEndLoc();
+
+ return SourceRange(StartLoc, EndLoc);
+}
+
const char *CastExpr::getCastKindName() const {
switch (getCastKind()) {
case CK_Dependent:
@@ -2017,6 +2039,42 @@ bool Expr::isTemporaryObject(ASTContext &C, const CXXRecordDecl *TempTy) const {
return true;
}
+bool Expr::isImplicitCXXThis() const {
+ const Expr *E = this;
+
+ // Strip away parentheses and casts we don't care about.
+ while (true) {
+ if (const ParenExpr *Paren = dyn_cast<ParenExpr>(E)) {
+ E = Paren->getSubExpr();
+ continue;
+ }
+
+ if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+ if (ICE->getCastKind() == CK_NoOp ||
+ ICE->getCastKind() == CK_LValueToRValue ||
+ ICE->getCastKind() == CK_DerivedToBase ||
+ ICE->getCastKind() == CK_UncheckedDerivedToBase) {
+ E = ICE->getSubExpr();
+ continue;
+ }
+ }
+
+ if (const UnaryOperator* UnOp = dyn_cast<UnaryOperator>(E)) {
+ if (UnOp->getOpcode() == UO_Extension) {
+ E = UnOp->getSubExpr();
+ continue;
+ }
+ }
+
+ break;
+ }
+
+ if (const CXXThisExpr *This = dyn_cast<CXXThisExpr>(E))
+ return This->isImplicit();
+
+ return false;
+}
+
/// hasAnyTypeDependentArguments - Determines if any of the expressions
/// in Exprs is type-dependent.
bool Expr::hasAnyTypeDependentArguments(Expr** Exprs, unsigned NumExprs) {
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index fb99dc9c86..3dac125990 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -783,46 +783,11 @@ CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C,
return E;
}
-/// \brief Determine whether this expression is an implicit C++ 'this'.
-static bool isImplicitThis(const Expr *E) {
- // Strip away parentheses and casts we don't care about.
- while (true) {
- if (const ParenExpr *Paren = dyn_cast<ParenExpr>(E)) {
- E = Paren->getSubExpr();
- continue;
- }
-
- if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
- if (ICE->getCastKind() == CK_NoOp ||
- ICE->getCastKind() == CK_LValueToRValue ||
- ICE->getCastKind() == CK_DerivedToBase ||
- ICE->getCastKind() == CK_UncheckedDerivedToBase) {
- E = ICE->getSubExpr();
- continue;
- }
- }
-
- if (const UnaryOperator* UnOp = dyn_cast<UnaryOperator>(E)) {
- if (UnOp->getOpcode() == UO_Extension) {
- E = UnOp->getSubExpr();
- continue;
- }
- }
-
- break;
- }
-
- if (const CXXThisExpr *This = dyn_cast<CXXThisExpr>(E))
- return This->isImplicit();
-
- return false;
-}
-
bool CXXDependentScopeMemberExpr::isImplicitAccess() const {
if (Base == 0)
return true;
- return isImplicitThis(cast<Expr>(Base));
+ return cast<Expr>(Base)->isImplicitCXXThis();
}
UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C,
@@ -851,7 +816,7 @@ bool UnresolvedMemberExpr::isImplicitAccess() const {
if (Base == 0)
return true;
- return isImplicitThis(cast<Expr>(Base));
+ return cast<Expr>(Base)->isImplicitCXXThis();
}
UnresolvedMemberExpr *