summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/Expr.h26
-rw-r--r--clang/lib/AST/StmtPrinter.cpp6
-rw-r--r--clang/lib/Sema/SemaExpr.cpp4
-rw-r--r--clang/lib/Sema/SemaInit.cpp1
4 files changed, 29 insertions, 8 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 0490aab2001..812b5ca642e 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -49,15 +49,21 @@ class Expr : public Stmt {
/// (C++ [temp.dep.constexpr]).
bool ValueDependent : 1;
+ /// Implicit - Whether this expression was implicitly created by the
+ /// implementation, rather than written explicitly by the user.
+ bool Implicit : 1;
+
protected:
// FIXME: Eventually, this constructor should go away and we should
// require every subclass to provide type/value-dependence
// information.
Expr(StmtClass SC, QualType T)
- : Stmt(SC), TypeDependent(false), ValueDependent(false) { setType(T); }
+ : Stmt(SC), TypeDependent(false), ValueDependent(false), Implicit(false) {
+ setType(T);
+ }
Expr(StmtClass SC, QualType T, bool TD, bool VD)
- : Stmt(SC), TypeDependent(TD), ValueDependent(VD) {
+ : Stmt(SC), TypeDependent(TD), ValueDependent(VD), Implicit(false) {
setType(T);
}
@@ -99,6 +105,14 @@ public:
/// @endcode
bool isTypeDependent() const { return TypeDependent; }
+ /// isImplicit - Determines whether this expression was implicitly
+ /// created by the implementation to express the semantics of an
+ /// implicit operation, such as an implicit conversion or implicit
+ /// reference to "this". When false, this expression was written
+ /// directly in the source code.
+ bool isImplicit() const { return Implicit; }
+ void setImplicit(bool I = true) { Implicit = I; }
+
/// SourceLocation tokens are not useful in isolation - they are low level
/// value objects created/interpreted by SourceManager. We assume AST
/// clients will have a pointer to the respective SourceManager.
@@ -982,7 +996,9 @@ class ImplicitCastExpr : public CastExpr {
public:
ImplicitCastExpr(QualType ty, Expr *op, bool Lvalue) :
- CastExpr(ImplicitCastExprClass, ty, op), LvalueCast(Lvalue) {}
+ CastExpr(ImplicitCastExprClass, ty, op), LvalueCast(Lvalue) {
+ setImplicit(true);
+ }
virtual SourceRange getSourceRange() const {
return getSubExpr()->getSourceRange();
@@ -1671,9 +1687,7 @@ public:
// Explicit InitListExpr's originate from source code (and have valid source
// locations). Implicit InitListExpr's are created by the semantic analyzer.
- bool isExplicit() {
- return LBraceLoc.isValid() && RBraceLoc.isValid();
- }
+ bool isExplicit() { return !isImplicit(); }
virtual SourceRange getSourceRange() const {
return SourceRange(LBraceLoc, RBraceLoc);
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 679c8974975..7456e8cca9e 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -757,8 +757,10 @@ void StmtPrinter::VisitCallExpr(CallExpr *Call) {
OS << ")";
}
void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
- PrintExpr(Node->getBase());
- OS << (Node->isArrow() ? "->" : ".");
+ if (!Node->getBase()->isImplicit()) {
+ PrintExpr(Node->getBase());
+ OS << (Node->isArrow() ? "->" : ".");
+ }
OS << Node->getMemberDecl()->getNameAsString();
}
void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index bf04042ef8a..6db6ea19afd 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -444,6 +444,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
BaseObjectExpr = new DeclRefExpr(BaseObject, BaseObject->getType(),
SourceLocation());
+ BaseObjectExpr->setImplicit();
ExtraQuals
= Context.getCanonicalType(BaseObject->getType()).getCVRQualifiers();
} else if (BaseObjectExpr) {
@@ -473,6 +474,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
BaseObjectExpr = new CXXThisExpr(SourceLocation(),
MD->getThisType(Context));
BaseObjectIsPointer = true;
+ BaseObjectExpr->setImplicit();
}
} else {
return Diag(Loc, diag::err_invalid_member_use_in_static_method)
@@ -500,6 +502,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
}
Result = new MemberExpr(Result, BaseObjectIsPointer, *FI,
OpLoc, MemberType);
+ Result->setImplicit();
BaseObjectIsPointer = false;
ExtraQuals = Context.getCanonicalType(MemberType).getCVRQualifiers();
OpLoc = SourceLocation();
@@ -661,6 +664,7 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// Build the implicit member access expression.
Expr *This = new CXXThisExpr(SourceLocation(),
MD->getThisType(Context));
+ This->setImplicit();
return new MemberExpr(This, true, cast<NamedDecl>(D),
SourceLocation(), MemberType);
}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 031fe27ddf7..6a9275fbe8a 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -90,6 +90,7 @@ void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
&InitExprs[0], InitExprs.size(),
SourceLocation(),
ParentIList->hadDesignators());
+ ILE->setImplicit();
ILE->setType(T);
// Modify the parent InitListExpr to point to the implicit InitListExpr.
OpenPOWER on IntegriCloud