summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-02-12 18:42:33 +0000
committerDouglas Gregor <dgregor@apple.com>2012-02-12 18:42:33 +0000
commit81495f341d4a8a06a1d775c31562a37dc2f9c7fe (patch)
tree3b34fb85073dac1f4dfb7a241b0522b6c9db1114 /clang/lib/AST
parentd74dd49065ba4109b8b04209fd197d85857d4281 (diff)
downloadbcm5719-llvm-81495f341d4a8a06a1d775c31562a37dc2f9c7fe.tar.gz
bcm5719-llvm-81495f341d4a8a06a1d775c31562a37dc2f9c7fe.zip
Within the body of a lambda expression, decltype((x)) for an
id-expression 'x' will compute the type based on the assumption that 'x' will be captured, even if it isn't captured, per C++11 [expr.prim.lambda]p18. There are two related refactors that go into implementing this: 1) Split out the check that determines whether we should capture a particular variable reference, along with the computation of the type of the field, from the actual act of capturing the variable. 2) Always compute the result of decltype() within Sema, rather than AST, because the decltype() computation is now context-sensitive. llvm-svn: 150347
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp37
-rw-r--r--clang/lib/AST/ASTImporter.cpp6
2 files changed, 8 insertions, 35 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index bb93a68d265..cc651f9c9c5 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2913,44 +2913,13 @@ QualType ASTContext::getTypeOfType(QualType tofType) const {
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, const ASTContext &Context) {
- if (e->isTypeDependent())
- return Context.DependentTy;
-
- // 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())
- 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 types (which are always unique).
-QualType ASTContext::getDecltypeType(Expr *e) const {
+QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {
DecltypeType *dt;
// C++0x [temp.type]p2:
@@ -2976,8 +2945,8 @@ QualType ASTContext::getDecltypeType(Expr *e) const {
dt = Canon;
}
} else {
- QualType T = getDecltypeForExpr(e, *this);
- dt = new (*this, TypeAlignment) DecltypeType(e, T, getCanonicalType(T));
+ dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
+ getCanonicalType(UnderlyingType));
}
Types.push_back(dt);
return QualType(dt, 0);
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 556f97d8582..e15bac0b447 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1581,7 +1581,11 @@ QualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
if (!ToExpr)
return QualType();
- return Importer.getToContext().getDecltypeType(ToExpr);
+ QualType UnderlyingType = Importer.Import(T->getUnderlyingType());
+ if (UnderlyingType.isNull())
+ return QualType();
+
+ return Importer.getToContext().getDecltypeType(ToExpr, UnderlyingType);
}
QualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
OpenPOWER on IntegriCloud