RAIIObjectsForParser.h revision 28bbe4b8acc338476fe0825769b41fb32b423c72
1d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner//===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- C++ -*-===//
2c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//
3c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//                     The LLVM Compiler Infrastructure
4c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//
5c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner// This file is distributed under the University of Illinois Open Source
6c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner// License. See LICENSE.TXT for details.
7c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//
8c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//===----------------------------------------------------------------------===//
9c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//
10d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner// This file defines and implements the some simple RAII objects that are used
11d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner// by the parser to manage bits in recursion.
12c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//
13c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//===----------------------------------------------------------------------===//
14c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner
15d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner#ifndef LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H
16d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner#define LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H
17c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner
18500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h"
19c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner
20c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattnernamespace clang {
21d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  // TODO: move ParsingDeclRAIIObject here.
22d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  // TODO: move ParsingClassDefinition here.
23d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  // TODO: move TentativeParsingAction here.
24d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner
25d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner
26c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// ExtensionRAIIObject - This saves the state of extension warnings when
27c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// constructed and disables them.  When destructed, it restores them back to
28c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// the way they used to be.  This is used to handle __extension__ in the
29c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// parser.
30c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  class ExtensionRAIIObject {
31c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    void operator=(const ExtensionRAIIObject &);     // DO NOT IMPLEMENT
32c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    ExtensionRAIIObject(const ExtensionRAIIObject&); // DO NOT IMPLEMENT
33c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    Diagnostic &Diags;
34c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  public:
35c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    ExtensionRAIIObject(Diagnostic &diags) : Diags(diags) {
3627ceb9d77d929f02a8a811d189a96885629c7c0cChris Lattner      Diags.IncrementAllExtensionsSilenced();
37c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    }
381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    ~ExtensionRAIIObject() {
4027ceb9d77d929f02a8a811d189a96885629c7c0cChris Lattner      Diags.DecrementAllExtensionsSilenced();
41c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    }
42c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  };
4308d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner
4408d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  /// ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and
4508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  /// restores it when destroyed.  This says that "foo:" should not be
4608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  /// considered a possible typo for "foo::" for error recovery purposes.
4708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  class ColonProtectionRAIIObject {
4808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    Parser &P;
4908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    bool OldVal;
5008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  public:
51932dff777d58a23e3a26967a61bb52697c542fd4Chris Lattner    ColonProtectionRAIIObject(Parser &p, bool Value = true)
52932dff777d58a23e3a26967a61bb52697c542fd4Chris Lattner      : P(p), OldVal(P.ColonIsSacred) {
53932dff777d58a23e3a26967a61bb52697c542fd4Chris Lattner      P.ColonIsSacred = Value;
5408d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    }
5508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner
566fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// restore - This can be used to restore the state early, before the dtor
576fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// is run.
586fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    void restore() {
5908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      P.ColonIsSacred = OldVal;
6008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    }
616fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner
626fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    ~ColonProtectionRAIIObject() {
636fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner      restore();
646fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    }
6508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  };
6608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner
67d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  /// \brief RAII object that makes '>' behave either as an operator
68d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  /// or as the closing angle bracket for a template argument list.
69648d846e4f140c30ab9d322870ea3fdd94debba2Benjamin Kramer  class GreaterThanIsOperatorScope {
70d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    bool &GreaterThanIsOperator;
71d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    bool OldGreaterThanIsOperator;
72648d846e4f140c30ab9d322870ea3fdd94debba2Benjamin Kramer  public:
73d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    GreaterThanIsOperatorScope(bool &GTIO, bool Val)
74d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    : GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) {
75d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner      GreaterThanIsOperator = Val;
76d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    }
77d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner
78d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    ~GreaterThanIsOperatorScope() {
79d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner      GreaterThanIsOperator = OldGreaterThanIsOperator;
80d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    }
81d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  };
82d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner
830fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  class InMessageExpressionRAIIObject {
840fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    bool &InMessageExpression;
850fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    bool OldValue;
860fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
870fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  public:
880fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    InMessageExpressionRAIIObject(Parser &P, bool Value)
890fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      : InMessageExpression(P.InMessageExpression),
900fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor        OldValue(P.InMessageExpression) {
910fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      InMessageExpression = Value;
920fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    }
930fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
940fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    ~InMessageExpressionRAIIObject() {
950fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      InMessageExpression = OldValue;
960fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    }
970fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  };
980fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
9936d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  /// \brief RAII object that makes sure paren/bracket/brace count is correct
10036d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  /// after declaration/statement parsing, even when there's a parsing error.
10136d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  class ParenBraceBracketBalancer {
10236d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    Parser &P;
10336d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    unsigned short ParenCount, BracketCount, BraceCount;
10436d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  public:
10536d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    ParenBraceBracketBalancer(Parser &p)
10636d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      : P(p), ParenCount(p.ParenCount), BracketCount(p.BracketCount),
10736d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis        BraceCount(p.BraceCount) { }
10836d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis
10936d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    ~ParenBraceBracketBalancer() {
11036d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      P.ParenCount = ParenCount;
11136d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      P.BracketCount = BracketCount;
11236d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      P.BraceCount = BraceCount;
11336d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    }
11436d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  };
11528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
11628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  class PoisonSEHIdentifiersRAIIObject {
11728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident_AbnormalTermination;
11828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident_GetExceptionCode;
11928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident_GetExceptionInfo;
12028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident__abnormal_termination;
12128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident__exception_code;
12228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident__exception_info;
12328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident___abnormal_termination;
12428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident___exception_code;
12528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident___exception_info;
12628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  public:
12728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonSEHIdentifiersRAIIObject(Parser &Self, bool NewValue)
12828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      : Ident_AbnormalTermination(Self.Ident_AbnormalTermination, NewValue),
12928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident_GetExceptionCode(Self.Ident_GetExceptionCode, NewValue),
13028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident_GetExceptionInfo(Self.Ident_GetExceptionInfo, NewValue),
13128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident__abnormal_termination(Self.Ident__abnormal_termination, NewValue),
13228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident__exception_code(Self.Ident__exception_code, NewValue),
13328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident__exception_info(Self.Ident__exception_info, NewValue),
13428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident___abnormal_termination(Self.Ident___abnormal_termination, NewValue),
13528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident___exception_code(Self.Ident___exception_code, NewValue),
13628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident___exception_info(Self.Ident___exception_info, NewValue) {
13728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    }
13828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  };
13928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
14008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner} // end namespace clang
141c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner
142c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner#endif
143