]> granicus.if.org Git - clang/commitdiff
implement a couple fixme's by implementing __extension__ properly.
authorChris Lattner <sabre@nondot.org>
Mon, 20 Oct 2008 06:45:43 +0000 (06:45 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 20 Oct 2008 06:45:43 +0000 (06:45 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57806 91177308-0d34-0410-b5e6-96231b3b80d8

clang.xcodeproj/project.pbxproj
lib/Parse/ExtensionRAIIObject.h [new file with mode: 0644]
lib/Parse/ParseDecl.cpp
lib/Parse/ParseExpr.cpp
lib/Parse/Parser.cpp

index 9e7791af5d9b3b41a0424343c279378cee04b879..7dd82b78f929e5d6a7ace53a8756d8ed36b30458 100644 (file)
                DE39857A0CB8ADCB00223765 /* ASTConsumers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ASTConsumers.cpp; path = Driver/ASTConsumers.cpp; sourceTree = "<group>"; };
                DE3986EF0CB8D4B300223765 /* IdentifierTable.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = IdentifierTable.h; sourceTree = "<group>"; tabWidth = 2; };
                DE3986F30CB8D50C00223765 /* IdentifierTable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IdentifierTable.cpp; sourceTree = "<group>"; };
+               DE3B90DE0EAC5EF200D01046 /* ExtensionRAIIObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExtensionRAIIObject.h; path = lib/Parse/ExtensionRAIIObject.h; sourceTree = "<group>"; };
                DE41211B0D7F1BBE0080F80A /* RValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RValues.h; path = clang/Analysis/PathSensitive/RValues.h; sourceTree = "<group>"; };
                DE41211D0D7F1BBE0080F80A /* GRWorkList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRWorkList.h; path = clang/Analysis/PathSensitive/GRWorkList.h; sourceTree = "<group>"; };
                DE41211E0D7F1BBE0080F80A /* SymbolManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SymbolManager.h; path = clang/Analysis/PathSensitive/SymbolManager.h; sourceTree = "<group>"; };
                DE1F22600A7D8C9B00FBF588 /* Parse */ = {
                        isa = PBXGroup;
                        children = (
+                               DE3B90DE0EAC5EF200D01046 /* ExtensionRAIIObject.h */,
                                3551068F0E9A857C006A4E44 /* ParsePragma.h */,
                                3551068A0E9A8546006A4E44 /* ParsePragma.cpp */,
                                3551068B0E9A8546006A4E44 /* ParseTentative.cpp */,
diff --git a/lib/Parse/ExtensionRAIIObject.h b/lib/Parse/ExtensionRAIIObject.h
new file mode 100644 (file)
index 0000000..e7d4446
--- /dev/null
@@ -0,0 +1,42 @@
+//===--- ExtensionRAIIObject.h - Use RAII for __extension__ -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines and implements the ExtensionRAIIObject class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_EXTENSION_RAII_OBJECT_H
+#define LLVM_CLANG_PARSE_EXTENSION_RAII_OBJECT_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+
+  /// ExtensionRAIIObject - This saves the state of extension warnings when
+  /// constructed and disables them.  When destructed, it restores them back to
+  /// the way they used to be.  This is used to handle __extension__ in the
+  /// parser.
+  class ExtensionRAIIObject {
+    void operator=(const ExtensionRAIIObject &);     // DO NOT IMPLEMENT
+    ExtensionRAIIObject(const ExtensionRAIIObject&); // DO NOT IMPLEMENT
+    Diagnostic &Diags;
+    bool OldState;
+  public:
+    ExtensionRAIIObject(Diagnostic &diags) : Diags(diags) {
+      OldState = Diags.getWarnOnExtensions();
+      Diags.setWarnOnExtensions(false);
+    }
+    
+    ~ExtensionRAIIObject() {
+      Diags.setWarnOnExtensions(OldState);
+    }
+  };
+}
+
+#endif
index 041d876f56709480de35b8e3767420c868ebaa44..27133d683c97a23208d7ec47e39ecbf2615c5b6a 100644 (file)
@@ -15,6 +15,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
+#include "ExtensionRAIIObject.h"
 #include "llvm/ADT/SmallSet.h"
 using namespace clang;
 
@@ -659,15 +660,16 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
 void Parser::
 ParseStructDeclaration(DeclSpec &DS,
                        llvm::SmallVectorImpl<FieldDeclarator> &Fields) {
-  // FIXME: When __extension__ is specified, disable extension diagnostics.
-  while (Tok.is(tok::kw___extension__))
+  if (Tok.is(tok::kw___extension__)) {
+    // __extension__ silences extension warnings in the subexpression.
+    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
     ConsumeToken();
+    return ParseStructDeclaration(DS, Fields);
+  }
   
   // Parse the common specifier-qualifiers-list piece.
   SourceLocation DSStart = Tok.getLocation();
   ParseSpecifierQualifierList(DS);
-  // TODO: Does specifier-qualifier list correctly check that *something* is
-  // specified?
   
   // If there are no declarators, issue a warning.
   if (Tok.is(tok::semi)) {
index d0f5eb2607662f2dfec7a19c3538f3d86248d738..f6d7037ad12a6acf3f6fd45f59f5139a7db5a434 100644 (file)
@@ -22,7 +22,7 @@
 #include "clang/Parse/Parser.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
-#include "clang/Basic/Diagnostic.h"
+#include "ExtensionRAIIObject.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/SmallString.h"
 using namespace clang;
@@ -521,13 +521,11 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
       
   case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
     // __extension__ silences extension warnings in the subexpression.
-    bool SavedExtWarn = Diags.getWarnOnExtensions();
-    Diags.setWarnOnExtensions(false);
+    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
     SourceLocation SavedLoc = ConsumeToken();
     Res = ParseCastExpression(false);
     if (!Res.isInvalid)
       Res = Actions.ActOnUnaryOp(SavedLoc, SavedKind, Res.Val);
-    Diags.setWarnOnExtensions(SavedExtWarn);
     return Res;
   }
   case tok::kw_sizeof:     // unary-expression: 'sizeof' unary-expression
index 1b3adb95c0c4623c7666ba7e0544f1e90816024a..e30e4f4fa8cade81a69b3da4cf2d7549ed9c7231 100644 (file)
@@ -15,6 +15,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
+#include "ExtensionRAIIObject.h"
 #include "ParsePragma.h"
 using namespace clang;
 
@@ -341,11 +342,9 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() {
     // TODO: Invoke action for top-level semicolon.
     return 0;
   case tok::kw___extension__: {
-    ConsumeToken();
-    // FIXME: Disable extension warnings.
-    DeclTy *RV = ParseExternalDeclaration();
-    // FIXME: Restore extension warnings.
-    return RV;
+    // __extension__ silences extension warnings in the subexpression.
+    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
+    return ParseExternalDeclaration();
   }
   case tok::kw_asm: {
     ExprResult Result = ParseSimpleAsm();