diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2008-11-21 19:14:01 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2008-11-21 19:14:01 +0000 |
commit | 4c5d320a7581f4b80b151630c91cea5727fa9923 (patch) | |
tree | 2ebb368fb49a811cb48d60dbda245007efb6d8b5 /lib/Sema/SemaType.cpp | |
parent | 730e0fdbbf9b315ef834074054ac55af3a4fcc0c (diff) |
Implementation of new and delete parsing and sema.
This version uses VLAs to represent arrays. I'll try an alternative way next, but I want this safe first.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59835 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r-- | lib/Sema/SemaType.cpp | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index a622c8afb8..7000c3f5be 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -250,14 +250,14 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) { /// GetTypeForDeclarator - Convert the type for the specified declarator to Type /// instances. -QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { +QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, bool CXXNewMode) { // long long is a C99 feature. if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x && D.getDeclSpec().getTypeSpecWidth() == DeclSpec::TSW_longlong) Diag(D.getDeclSpec().getTypeSpecWidthLoc(), diag::ext_longlong); QualType T = ConvertDeclSpecToType(D.getDeclSpec()); - + // Walk the DeclTypeInfo, building the recursive type as we go. DeclTypeInfos // are ordered from the identifier out, which is opposite of what we want :). for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { @@ -340,6 +340,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { break; } case DeclaratorChunk::Array: { + // Only the outermost dimension gets special treatment. + bool UseCXXNewMode = CXXNewMode && i == e-1; DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr; Expr *ArraySize = static_cast<Expr*>(ATI.NumElts); ArrayType::ArraySizeModifier ASM; @@ -394,9 +396,11 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { if (!ArraySize) { T = Context.getIncompleteArrayType(T, ASM, ATI.TypeQuals); } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context) || - !T->isConstantSizeType()) { + !T->isConstantSizeType() || UseCXXNewMode) { // Per C99, a variable array is an array with either a non-constant // size or an element type that has a non-constant-size + // We also force this for parsing C++ new-expressions, since the + // outermost dimension is always treated as variable. T = Context.getVariableArrayType(T, ArraySize, ASM, ATI.TypeQuals); } else { // C99 6.7.5.2p1: If the expression is a constant expression, it shall @@ -416,7 +420,9 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { T = Context.getConstantArrayType(T, ConstVal, ASM, ATI.TypeQuals); } // If this is not C99, extwarn about VLA's and C99 array size modifiers. - if (!getLangOptions().C99 && + // Unless we're in C++ new mode. ActOnCXXNew will complain about them + // there, and they're hard errors. + if (!getLangOptions().C99 && !CXXNewMode && (ASM != ArrayType::Normal || (ArraySize && !ArraySize->isIntegerConstantExpr(Context)))) Diag(D.getIdentifierLoc(), diag::ext_vla); @@ -614,12 +620,12 @@ bool Sema::UnwrapSimilarPointerTypes(QualType& T1, QualType& T2) return false; } -Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) { +Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D, bool CXXNewMode) { // C99 6.7.6: Type names have no identifier. This is already validated by // the parser. assert(D.getIdentifier() == 0 && "Type name should have no identifier!"); - QualType T = GetTypeForDeclarator(D, S); + QualType T = GetTypeForDeclarator(D, S, CXXNewMode); assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); |