aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-08-22 15:38:55 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-08-22 15:38:55 +0000
commit987a14bf5883ef6e5d07f1c83eb6d41a8212a78c (patch)
treed5691abce8108c4987271f3bcf4a2fb4c147640a /lib/Sema/SemaExprCXX.cpp
parentdfb99a968b3cebe4ca5dd7941f228678f2cb3566 (diff)
Add support for C++'s "type-specifier ( expression-list )" expression:
-The Parser calls a new "ActOnCXXTypeConstructExpr" action. -Sema, depending on the type and expressions number: -If the type is a class, it will treat it as a class constructor. [TODO] -If there's only one expression (i.e. "int(0.5)" ), creates a new "CXXFunctionalCastExpr" Expr node -If there are no expressions (i.e "int()" ), creates a new "CXXZeroInitValueExpr" Expr node. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55177 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r--lib/Sema/SemaExprCXX.cpp64
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);
+}