diff options
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 86e334580c..1c723e69b3 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -68,3 +68,67 @@ Action::ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) { return Diag(ThisLoc, diag::err_invalid_this_use); } + +/// ActOnCXXTypeConstructExpr - Parse construction of a specified type. +/// Can be interpreted either as function-style casting ("int(x)") +/// or class type construction ("ClassType(x,y,z)") +/// or creation of a value-initialized type ("int()"). +Action::ExprResult +Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, + SourceLocation LParenLoc, + ExprTy **ExprTys, unsigned NumExprs, + SourceLocation *CommaLocs, + SourceLocation RParenLoc) { + assert(TypeRep && "Missing type!"); + QualType Ty = QualType::getFromOpaquePtr(TypeRep); + Expr **Exprs = (Expr**)ExprTys; + SourceLocation TyBeginLoc = TypeRange.getBegin(); + SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc); + + if (const RecordType *RT = Ty->getAsRecordType()) { + // C++ 5.2.3p1: + // If the simple-type-specifier specifies a class type, the class type shall + // be complete. + // + if (!RT->getDecl()->isDefinition()) + return Diag(TyBeginLoc, diag::err_invalid_incomplete_type_use, + Ty.getAsString(), FullRange); + + // "class constructors are not supported yet" + return Diag(TyBeginLoc, diag::err_unsupported_class_constructor, FullRange); + } + + // C++ 5.2.3p1: + // If the expression list is a single expression, the type conversion + // expression is equivalent (in definedness, and if defined in meaning) to the + // corresponding cast expression. + // + if (NumExprs == 1) { + if (CheckCastTypes(TypeRange, Ty, Exprs[0])) + return true; + return new CXXFunctionalCastExpr(Ty, TyBeginLoc, Exprs[0], RParenLoc); + } + + // C++ 5.2.3p1: + // If the expression list specifies more than a single value, the type shall + // be a class with a suitably declared constructor. + // + if (NumExprs > 1) + return Diag(CommaLocs[0], diag::err_builtin_func_cast_more_than_one_arg, + FullRange); + + assert(NumExprs == 0 && "Expected 0 expressions"); + + // C++ 5.2.3p2: + // The expression T(), where T is a simple-type-specifier for a non-array + // complete object type or the (possibly cv-qualified) void type, creates an + // rvalue of the specified type, which is value-initialized. + // + if (Ty->isArrayType()) + return Diag(TyBeginLoc, diag::err_value_init_for_array_type, FullRange); + if (Ty->isIncompleteType() && !Ty->isVoidType()) + return Diag(TyBeginLoc, diag::err_invalid_incomplete_type_use, + Ty.getAsString(), FullRange); + + return new CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc); +} |