refactor the 'ColonIsSacred' argument to ParseOptionalCXXScopeSpecifier

to be a bool in Parser that is twiddled by the ColonProtectionRAIIObject
class.  No functionality change.

llvm-svn: 91014
This commit is contained in:
Chris Lattner 2009-12-10 00:32:41 +00:00
parent 633c6f6f36
commit d5c1c9d0ae
5 changed files with 40 additions and 13 deletions

View File

@ -30,6 +30,7 @@ namespace clang {
class DiagnosticBuilder;
class Parser;
class PragmaUnusedHandler;
class ColonProtectionRAIIObject;
/// PrettyStackTraceParserEntry - If a crash happens while the parser is active,
/// an entry is printed for it.
@ -47,6 +48,7 @@ public:
///
class Parser {
friend class PragmaUnusedHandler;
friend class ColonProtectionRAIIObject;
PrettyStackTraceParserEntry CrashInfo;
Preprocessor &PP;
@ -90,6 +92,12 @@ class Parser {
/// template argument list, where the '>' closes the template
/// argument list.
bool GreaterThanIsOperator;
/// ColonIsSacred - When this is false, we aggressively try to recover from
/// code like "foo : bar" as if it were a typo for "foo :: bar". This is not
/// safe in case statements and a few other things. This is managed by the
/// ColonProtectionRAIIObject RAII object.
bool ColonIsSacred;
/// The "depth" of the template parameters currently being parsed.
unsigned TemplateParameterDepth;
@ -890,8 +898,7 @@ private:
bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
TypeTy *ObjectType,
bool EnteringContext,
bool ColonIsSacred = false);
bool EnteringContext);
//===--------------------------------------------------------------------===//
// C++ 5.2p1: C++ Casts

View File

@ -601,10 +601,14 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// Parse the (optional) nested-name-specifier.
CXXScopeSpec SS;
if (getLang().CPlusPlus &&
ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true, true))
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
Diag(Tok, diag::err_expected_ident);
if (getLang().CPlusPlus) {
// "FOO : BAR" is not a potential typo for "FOO::BAR".
ColonProtectionRAIIObject X(*this);
if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true))
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
Diag(Tok, diag::err_expected_ident);
}
TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;

View File

@ -45,14 +45,10 @@ using namespace clang;
/// \param EnteringContext whether we will be entering into the context of
/// the nested-name-specifier after parsing it.
///
/// \param ColonIsSacred - If this is true, then a colon is valid after the
/// specifier, so we should not try to recover from colons aggressively.
///
/// \returns true if a scope specifier was parsed.
bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
Action::TypeTy *ObjectType,
bool EnteringContext,
bool ColonIsSacred) {
bool EnteringContext) {
assert(getLang().CPlusPlus &&
"Call sites of this function should be guarded by checking for C++");

View File

@ -36,7 +36,8 @@ public:
Parser::Parser(Preprocessor &pp, Action &actions)
: CrashInfo(*this), PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
GreaterThanIsOperator(true), TemplateParameterDepth(0) {
GreaterThanIsOperator(true), ColonIsSacred(false),
TemplateParameterDepth(0) {
Tok.setKind(tok::eof);
CurScope = 0;
NumCachedScopes = 0;

View File

@ -36,6 +36,25 @@ namespace clang {
Diags.DecrementAllExtensionsSilenced();
}
};
}
// TODO: move GreaterThanIsOperatorScope here.
/// ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and
/// restores it when destroyed. This says that "foo:" should not be
/// considered a possible typo for "foo::" for error recovery purposes.
class ColonProtectionRAIIObject {
Parser &P;
bool OldVal;
public:
ColonProtectionRAIIObject(Parser &p) : P(p), OldVal(P.ColonIsSacred) {
P.ColonIsSacred = true;
}
~ColonProtectionRAIIObject() {
P.ColonIsSacred = OldVal;
}
};
} // end namespace clang
#endif