diff options
author | ed <ed@FreeBSD.org> | 2009-06-27 10:45:02 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-06-27 10:45:02 +0000 |
commit | c1ff020ff2d3e7ba86f7ab986ac7569c34f2ab1a (patch) | |
tree | 2c5a83521a20c02e7805581a174008aa9bc23579 /lib/AST/ASTContext.cpp | |
parent | 14660dbe9881f68a6cc2b9f014e1fb7b7228bca4 (diff) | |
download | FreeBSD-src-c1ff020ff2d3e7ba86f7ab986ac7569c34f2ab1a.zip FreeBSD-src-c1ff020ff2d3e7ba86f7ab986ac7569c34f2ab1a.tar.gz |
Import Clang r74383.
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index b80142f..12f75ae 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -179,6 +179,10 @@ void ASTContext::InitBuiltinTypes() { // expressions. InitBuiltinType(DependentTy, BuiltinType::Dependent); + // Placeholder type for C++0x auto declarations whose real type has + // not yet been deduced. + InitBuiltinType(UndeducedAutoTy, BuiltinType::UndeducedAuto); + // C99 6.2.5p11. FloatComplexTy = getComplexType(FloatTy); DoubleComplexTy = getComplexType(DoubleTy); @@ -460,6 +464,10 @@ ASTContext::getTypeInfo(const Type *T) { case Type::TypeOf: return getTypeInfo(cast<TypeOfType>(T)->getUnderlyingType().getTypePtr()); + case Type::Decltype: + return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType() + .getTypePtr()); + case Type::QualifiedName: return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr()); @@ -1659,6 +1667,50 @@ 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->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(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) { + QualType T = getDecltypeForExpr(e, *this); + DecltypeType *dt = new (*this, 8) DecltypeType(e, getCanonicalType(T)); + Types.push_back(dt); + return QualType(dt, 0); +} + /// getTagDeclType - Return the unique reference to the type for the /// specified TagDecl (struct/union/class/enum) decl. QualType ASTContext::getTagDeclType(TagDecl *Decl) { |