From: Chris Lattner Date: Mon, 20 Oct 2008 06:45:43 +0000 (+0000) Subject: implement a couple fixme's by implementing __extension__ properly. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c46d1a1f8af67a87689d7db9eaf96027282ccaea;p=clang implement a couple fixme's by implementing __extension__ properly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57806 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index 9e7791af5d..7dd82b78f9 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -423,6 +423,7 @@ DE39857A0CB8ADCB00223765 /* ASTConsumers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ASTConsumers.cpp; path = Driver/ASTConsumers.cpp; sourceTree = ""; }; DE3986EF0CB8D4B300223765 /* IdentifierTable.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = IdentifierTable.h; sourceTree = ""; tabWidth = 2; }; DE3986F30CB8D50C00223765 /* IdentifierTable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IdentifierTable.cpp; sourceTree = ""; }; + DE3B90DE0EAC5EF200D01046 /* ExtensionRAIIObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExtensionRAIIObject.h; path = lib/Parse/ExtensionRAIIObject.h; sourceTree = ""; }; DE41211B0D7F1BBE0080F80A /* RValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RValues.h; path = clang/Analysis/PathSensitive/RValues.h; sourceTree = ""; }; DE41211D0D7F1BBE0080F80A /* GRWorkList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRWorkList.h; path = clang/Analysis/PathSensitive/GRWorkList.h; sourceTree = ""; }; DE41211E0D7F1BBE0080F80A /* SymbolManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SymbolManager.h; path = clang/Analysis/PathSensitive/SymbolManager.h; sourceTree = ""; }; @@ -755,6 +756,7 @@ 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 index 0000000000..e7d44464b5 --- /dev/null +++ b/lib/Parse/ExtensionRAIIObject.h @@ -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 diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 041d876f56..27133d683c 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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 &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)) { diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index d0f5eb2607..f6d7037ad1 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -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 diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 1b3adb95c0..e30e4f4fa8 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -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();