]> granicus.if.org Git - clang/commitdiff
Implement a hack intended to allow Clang to parse libstdc++ 4.5's
authorDouglas Gregor <dgregor@apple.com>
Fri, 11 Mar 2011 23:10:44 +0000 (23:10 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 11 Mar 2011 23:10:44 +0000 (23:10 +0000)
headers, which use C++0x generalized initializer lists. Per PR7069, it
appears that the only use is as the return type of a function, so this
commit enables this extension just in that narrow case. If it's enough
for libstdc++ 4.5, or if it can be trivially extended to work with
libstdc++ 4.5, we'll keep it. Otherwise, or if this breaks anything,
we'll revert and wait for the real feature.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127507 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseStmt.cpp
test/SemaCXX/cxx0x-return-init-list.cpp [new file with mode: 0644]

index f36d74645c2177885d37f706f5e1eb2b287eaddc..0f011f574136202a68194c8ff5f342a37afcca35 100644 (file)
@@ -178,6 +178,9 @@ def ext_ref_qualifier : ExtWarn<
   "reference qualifiers on functions are a C++0x extension">, InGroup<CXX0x>;
 def ext_inline_namespace : ExtWarn<
   "inline namespaces are a C++0x feature">, InGroup<CXX0x>;
+def ext_generalized_initializer_lists : ExtWarn<
+  "generalized initializer lists are a C++0x extension unsupported in Clang">,
+  InGroup<CXX0x>;
 def err_argument_required_after_attribute : Error<
   "argument required after attribute">;
 def err_missing_param : Error<"expected parameter declarator">;
index d1376accca9002a047772f66569b2b65ad47aba4..d7e9070520d682f91416b982189132da6a505211 100644 (file)
@@ -1267,7 +1267,16 @@ StmtResult Parser::ParseReturnStatement(ParsedAttributes &attrs) {
       return StmtError();
     }
         
-    R = ParseExpression();
+    // FIXME: This is a hack to allow something like C++0x's generalized
+    // initializer lists, but only enough of this feature to allow Clang to
+    // parse libstdc++ 4.5's headers.
+    if (Tok.is(tok::l_brace) && getLang().CPlusPlus) {
+      R = ParseInitializer();
+      if (R.isUsable() && !getLang().CPlusPlus0x)
+        Diag(R.get()->getLocStart(), diag::ext_generalized_initializer_lists)
+          << R.get()->getSourceRange();
+    } else
+        R = ParseExpression();
     if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.
       SkipUntil(tok::semi, false, true);
       return StmtError();
diff --git a/test/SemaCXX/cxx0x-return-init-list.cpp b/test/SemaCXX/cxx0x-return-init-list.cpp
new file mode 100644 (file)
index 0000000..2005a7f
--- /dev/null
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This test checks for a teeny tiny subset of the functionality in
+// the C++0x generalized initializer lists feature, which happens to
+// be used in libstdc++ 4.5. We accept only this syntax so that Clang
+// can handle the libstdc++ 4.5 headers.
+
+int test0(int i) {
+  return { i }; // expected-warning{{generalized initializer lists are a C++0x extension unsupported in Clang}}
+}
+
+template<typename T, typename U>
+T test1(U u) {
+  return { u }; // expected-warning{{generalized initializer lists are a C++0x extension unsupported in Clang}}
+}
+
+template int test1(char);
+template long test1(int);