aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-06-24 21:24:56 +0000
committerAnders Carlsson <andersca@mac.com>2009-06-24 21:24:56 +0000
commit60a9a2a404a4cf259d39133383e922aa00ca9043 (patch)
tree5dece031a065bcb20b0eda724eaab055a37a3e57 /lib/AST/ASTContext.cpp
parent08fa2af5f60cdcb65b554ce2afe39016475cade4 (diff)
C++ decltype support (N2343)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74118 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r--lib/AST/ASTContext.cpp34
1 files changed, 31 insertions, 3 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e23bb34b05..377d2fbe9a 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1663,15 +1663,43 @@ QualType ASTContext::getTypeOfType(QualType tofType) {
return QualType(tot, 0);
}
+/// getDecltypeForExpr - Given an expr, will return the decltype for that
+/// expression, according to the rules in C++0x [dcl.type.simple]p4
+static QualType getDecltypeForExpr(const Expr *e, ASTContext &Context) {
+ // If e is an id expression or a class member access, decltype(e) is defined
+ // as the type of the entity named by e.
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(e)) {
+ if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl()))
+ return VD->getType();
+ }
+ if (const MemberExpr *ME = dyn_cast<MemberExpr>(e)) {
+ if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
+ return FD->getType();
+ }
+ // If e is a function call or an invocation of an overloaded operator,
+ // (parentheses around e are ignored), decltype(e) is defined as the
+ // return type of that function.
+ if (const CallExpr *CE = dyn_cast<CallExpr>(e->IgnoreParens()))
+ return CE->getCallReturnType();
+
+ QualType T = e->getType();
+
+ // Otherwise, where T is the type of e, if e is an lvalue, decltype(e) is
+ // defined as T&, otherwise decltype(e) is defined as T.
+ if (e->isLvalue(Context) == Expr::LV_Valid)
+ T = Context.getLValueReferenceType(T);
+
+ return T;
+}
+
/// getDecltypeType - Unlike many "get<Type>" functions, we don't unique
/// DecltypeType AST's. The only motivation to unique these nodes would be
/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
/// an issue. This doesn't effect the type checker, since it operates
/// on canonical type's (which are always unique).
QualType ASTContext::getDecltypeType(Expr *e) {
- // FIXME: Use the right type here!
- QualType Canonical = getCanonicalType(e->getType());
- DecltypeType *dt = new (*this, 8) DecltypeType(e, Canonical);
+ QualType T = getDecltypeForExpr(e, *this);
+ DecltypeType *dt = new (*this, 8) DecltypeType(e, getCanonicalType(T));
Types.push_back(dt);
return QualType(dt, 0);
}