diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-02-26 14:39:58 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-02-26 14:39:58 +0000 |
commit | 2850784bda09416fc7e9d57f5baa36c9351c757c (patch) | |
tree | 3986bb7f764a4b327e512f1b1ed85bd048a37ec5 /lib/Sema/SemaExprCXX.cpp | |
parent | b558422a49dbf97d560e493fb1573d44f0abe221 (diff) |
Make more AST nodes and semantic checkers dependent-expression-aware.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65529 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 77 |
1 files changed, 45 insertions, 32 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index c8671bc2e3..6023469193 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -134,6 +134,8 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, TyBeginLoc, Exprs[0], RParenLoc); } + // FIXME: What AST node to create when the type is dependent? + if (const RecordType *RT = Ty->getAsRecordType()) { CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl()); @@ -220,14 +222,16 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, if (CheckAllocatedType(AllocType, D)) return true; - QualType ResultType = Context.getPointerType(AllocType); + QualType ResultType = AllocType->isDependentType() + ? Context.DependentTy + : Context.getPointerType(AllocType); // That every array dimension except the first is constant was already // checked by the type check above. // C++ 5.3.4p6: "The expression in a direct-new-declarator shall have integral // or enumeration type with a non-negative value." - if (ArraySize) { + if (ArraySize && !ArraySize->isTypeDependent()) { QualType SizeType = ArraySize->getType(); if (!SizeType->isIntegralType() && !SizeType->isEnumeralType()) return Diag(ArraySize->getSourceRange().getBegin(), @@ -236,20 +240,24 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, // Let's see if this is a constant < 0. If so, we reject it out of hand. // We don't care about special rules, so we tell the machinery it's not // evaluated - it gives us a result in more cases. - llvm::APSInt Value; - if (ArraySize->isIntegerConstantExpr(Value, Context, 0, false)) { - if (Value < llvm::APSInt( - llvm::APInt::getNullValue(Value.getBitWidth()), false)) - return Diag(ArraySize->getSourceRange().getBegin(), - diag::err_typecheck_negative_array_size) - << ArraySize->getSourceRange(); + if (!ArraySize->isValueDependent()) { + llvm::APSInt Value; + if (ArraySize->isIntegerConstantExpr(Value, Context, 0, false)) { + if (Value < llvm::APSInt( + llvm::APInt::getNullValue(Value.getBitWidth()), false)) + return Diag(ArraySize->getSourceRange().getBegin(), + diag::err_typecheck_negative_array_size) + << ArraySize->getSourceRange(); + } } } FunctionDecl *OperatorNew = 0; FunctionDecl *OperatorDelete = 0; Expr **PlaceArgs = (Expr**)PlacementArgs; - if (FindAllocationFunctions(StartLoc, + if (!AllocType->isDependentType() && + !Expr::hasAnyTypeDependentArguments(PlaceArgs, NumPlaceArgs) && + FindAllocationFunctions(StartLoc, SourceRange(PlacementLParen, PlacementRParen), UseGlobal, AllocType, ArraySize, PlaceArgs, NumPlaceArgs, OperatorNew, OperatorDelete)) @@ -275,8 +283,11 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, // 2) Otherwise, the object is direct-initialized. CXXConstructorDecl *Constructor = 0; Expr **ConsArgs = (Expr**)ConstructorArgs; + if (AllocType->isDependentType()) { + // Skip all the checks. + } // FIXME: Should check for primitive/aggregate here, not record. - if (const RecordType *RT = AllocType->getAsRecordType()) { + else if (const RecordType *RT = AllocType->getAsRecordType()) { // FIXME: This is incorrect for when there is an empty initializer and // no user-defined constructor. Must zero-initialize, not default-construct. Constructor = PerformInitializationByConstructor( @@ -570,31 +581,33 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, // DR599 amends "pointer type" to "pointer to object type" in both cases. Expr *Ex = (Expr *)Operand; - QualType Type = Ex->getType(); + if (!Ex->isTypeDependent()) { + QualType Type = Ex->getType(); - if (Type->isRecordType()) { - // FIXME: Find that one conversion function and amend the type. - } + if (Type->isRecordType()) { + // FIXME: Find that one conversion function and amend the type. + } - if (!Type->isPointerType()) { - Diag(StartLoc, diag::err_delete_operand) << Type << Ex->getSourceRange(); - return true; - } + if (!Type->isPointerType()) { + Diag(StartLoc, diag::err_delete_operand) << Type << Ex->getSourceRange(); + return true; + } - QualType Pointee = Type->getAsPointerType()->getPointeeType(); - if (!Pointee->isVoidType() && - DiagnoseIncompleteType(StartLoc, Pointee, diag::warn_delete_incomplete, - Ex->getSourceRange())) - return true; - else if (!Pointee->isObjectType()) { - Diag(StartLoc, diag::err_delete_operand) - << Type << Ex->getSourceRange(); - return true; - } + QualType Pointee = Type->getAsPointerType()->getPointeeType(); + if (!Pointee->isVoidType() && + DiagnoseIncompleteType(StartLoc, Pointee, diag::warn_delete_incomplete, + Ex->getSourceRange())) + return true; + else if (!Pointee->isObjectType()) { + Diag(StartLoc, diag::err_delete_operand) + << Type << Ex->getSourceRange(); + return true; + } - // FIXME: Look up the correct operator delete overload and pass a pointer - // along. - // FIXME: Check access and ambiguity of operator delete and destructor. + // FIXME: Look up the correct operator delete overload and pass a pointer + // along. + // FIXME: Check access and ambiguity of operator delete and destructor. + } return new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm, 0, Ex, StartLoc); |