Tighten up handling of __func__ and friends: it should be an array
of const char, and it should error if it occurs outside a function.

Is it valid in an objc method?  If so we should handle that too.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45910 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index 88ee864..1e81d5c 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -115,25 +115,23 @@
   PreDefinedExpr::IdentType IT;
   
   switch (Kind) {
-  default:
-    assert(0 && "Unknown simple primary expr!");
-  case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]
-    IT = PreDefinedExpr::Func;
-    break;
-  case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]
-    IT = PreDefinedExpr::Function;
-    break;
-  case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU]
-    IT = PreDefinedExpr::PrettyFunction;
-    break;
+  default: assert(0 && "Unknown simple primary expr!");
+  case tok::kw___func__: IT = PreDefinedExpr::Func; break; // [C99 6.4.2.2]
+  case tok::kw___FUNCTION__: IT = PreDefinedExpr::Function; break;
+  case tok::kw___PRETTY_FUNCTION__: IT = PreDefinedExpr::PrettyFunction; break;
   }
+
+  // Verify that this is in a function context.
+  if (CurFunctionDecl == 0)
+    return Diag(Loc, diag::err_predef_outside_function);
   
   // Pre-defined identifiers are of type char[x], where x is the length of the
   // string.
   llvm::APSInt Length(32);
   Length = CurFunctionDecl->getIdentifier()->getLength() + 1;
-  QualType ResTy = Context.getConstantArrayType(Context.CharTy, Length,
-                                                ArrayType::Normal, 0);
+  
+  QualType ResTy = Context.CharTy.getQualifiedType(QualType::Const);
+  ResTy = Context.getConstantArrayType(ResTy, Length, ArrayType::Normal, 0);
   return new PreDefinedExpr(Loc, ResTy, IT);
 }