Fixed TypeofExpr AST and code generation.
authorAbramo Bagnara <abramo.bagnara@gmail.com>
Sat, 7 Jan 2012 10:52:36 +0000 (10:52 +0000)
committerAbramo Bagnara <abramo.bagnara@gmail.com>
Sat, 7 Jan 2012 10:52:36 +0000 (10:52 +0000)
llvm-svn: 147730

clang/include/clang/Sema/Sema.h
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/Parse/ParseDecl.cpp
clang/lib/Sema/SemaDecl.cpp
clang/test/CodeGen/vla.c

index 389cf8a..b686d2d 100644 (file)
@@ -1146,8 +1146,6 @@ public:
                                    DeclSpec &DS,
                                    MultiTemplateParamsArg TemplateParams);
 
-  StmtResult ActOnVlaStmt(const DeclSpec &DS);
-
   Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
                                     AccessSpecifier AS,
                                     RecordDecl *Record);
index 62d18ea..cde2de9 100644 (file)
@@ -929,19 +929,33 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
 
   // We're going to walk down into the type and look for VLA
   // expressions.
-  type = type.getCanonicalType();
   do {
     assert(type->isVariablyModifiedType());
 
     const Type *ty = type.getTypePtr();
     switch (ty->getTypeClass()) {
+
+    default:
+      // Only sugared types (different from typeof_expr) can reach this point.
+      assert(!type.isCanonical() && "unhandled canonical type!");
+      type = type.getSingleStepDesugaredType(getContext());
+      break;
+
+    case Type::TypeOfExpr: {
+      // This is the only sugared type requiring special treatment.
+      // Emit typeof expression and we are done.
+      Expr *E = cast<TypeOfExprType>(ty)->getUnderlyingExpr();
+      EmitIgnoredExpr(E);
+      return;
+    }
+
 #define TYPE(Class, Base)
 #define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_TYPE(Class, Base)
 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
 #include "clang/AST/TypeNodes.def"
-      llvm_unreachable("unexpected dependent or non-canonical type!");
+      llvm_unreachable("unexpected dependent type!");
 
     // These types are never variably-modified.
     case Type::Builtin:
@@ -999,7 +1013,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
       break;
     }
 
-    case Type::FunctionProto: 
+    case Type::FunctionProto:
     case Type::FunctionNoProto:
       type = cast<FunctionType>(ty)->getResultType();
       break;
index ee4a51e..1632149 100644 (file)
@@ -962,10 +962,7 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(StmtVector &Stmts,
 
   ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
                              getDeclSpecContextFromDeclaratorContext(Context));
-  StmtResult R = Actions.ActOnVlaStmt(DS);
-  if (R.isUsable())
-    Stmts.push_back(R.release());
-  
+
   // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
   // declaration-specifiers init-declarator-list[opt] ';'
   if (Tok.is(tok::semi)) {
index d1bf3db..d80f22f 100644 (file)
@@ -2481,25 +2481,6 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
   return TagD;
 }
 
-/// ActOnVlaStmt - This rouine if finds a vla expression in a decl spec.
-/// builds a statement for it and returns it so it is evaluated.
-StmtResult Sema::ActOnVlaStmt(const DeclSpec &DS) {
-  StmtResult R;
-  if (DS.getTypeSpecType() == DeclSpec::TST_typeofExpr) {
-    Expr *Exp = DS.getRepAsExpr();
-    QualType Ty = Exp->getType();
-    if (Ty->isPointerType()) {
-      do
-        Ty = Ty->getAs<PointerType>()->getPointeeType();
-      while (Ty->isPointerType());
-    }
-    if (Ty->isVariableArrayType()) {
-      R = ActOnExprStmt(MakeFullExpr(Exp));
-    }
-  }
-  return R;
-}
-
 /// We are trying to inject an anonymous member into the given scope;
 /// check if there's an existing declaration that can't be overloaded.
 ///
index c9612bc..9e62da5 100644 (file)
@@ -116,9 +116,6 @@ int test4(unsigned n, char (*p)[n][n+1][6]) {
   // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4
   // CHECK-NEXT: [[DIM1:%.*]] = add i32 [[T0]], 1
 
-  // __typeof.  FIXME: does this really need to be loaded?
-  // CHECK-NEXT: load [6 x i8]** [[P]]
-
   // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]** [[P]], align 4
   // CHECK-NEXT: [[T1:%.*]] = load i32* [[N]], align 4
   // CHECK-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2