summaryrefslogtreecommitdiffstats
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-06-27 10:45:02 +0000
committered <ed@FreeBSD.org>2009-06-27 10:45:02 +0000
commitc1ff020ff2d3e7ba86f7ab986ac7569c34f2ab1a (patch)
tree2c5a83521a20c02e7805581a174008aa9bc23579 /lib/AST/ASTContext.cpp
parent14660dbe9881f68a6cc2b9f014e1fb7b7228bca4 (diff)
downloadFreeBSD-src-c1ff020ff2d3e7ba86f7ab986ac7569c34f2ab1a.zip
FreeBSD-src-c1ff020ff2d3e7ba86f7ab986ac7569c34f2ab1a.tar.gz
Import Clang r74383.
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r--lib/AST/ASTContext.cpp52
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) {
OpenPOWER on IntegriCloud