aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2008-11-21 19:14:01 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2008-11-21 19:14:01 +0000
commit4c5d320a7581f4b80b151630c91cea5727fa9923 (patch)
tree2ebb368fb49a811cb48d60dbda245007efb6d8b5 /lib/Sema/SemaType.cpp
parent730e0fdbbf9b315ef834074054ac55af3a4fcc0c (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.cpp18
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");