From 314fe782fda562d1fe7d14d7135cc3f7736321c0 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 26 Nov 2008 22:40:03 +0000 Subject: [PATCH] Attempt to unravel the if/else mess in Parser::ParseDirectDeclarator. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60124 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Parse/ParseDecl.cpp | 118 +++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 44 deletions(-) diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 71353d27b6..4280c6050c 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1431,59 +1431,88 @@ void Parser::ParseDeclaratorInternal(Declarator &D, /// template-id [TODO] /// void Parser::ParseDirectDeclarator(Declarator &D) { - CXXScopeSpec &SS = D.getCXXScopeSpec(); - DeclaratorScopeObj DeclScopeObj(*this, SS); - - if (D.mayHaveIdentifier() && - getLang().CPlusPlus && MaybeParseCXXScopeSpecifier(SS)) { - // Change the declaration context for name lookup, until this function is - // exited (and the declarator has been parsed). - DeclScopeObj.EnterDeclaratorScope(); - } + DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec()); - // Parse the first direct-declarator seen. - if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) { - assert(Tok.getIdentifierInfo() && "Not an identifier?"); - // Determine whether this identifier is a C++ constructor name or - // a normal identifier. - if (getLang().CPlusPlus && - Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope)) - D.setConstructor(Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope), - Tok.getLocation()); - else - D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); - ConsumeToken(); - } else if (getLang().CPlusPlus && - Tok.is(tok::tilde) && D.mayHaveIdentifier()) { - // This should be a C++ destructor. - SourceLocation TildeLoc = ConsumeToken(); - if (Tok.is(tok::identifier)) { - if (TypeTy *Type = ParseClassName()) - D.setDestructor(Type, TildeLoc); - else - D.SetIdentifier(0, TildeLoc); - } else { - Diag(Tok, diag::err_expected_class_name); - D.SetIdentifier(0, TildeLoc); + if (getLang().CPlusPlus) { + if (D.mayHaveIdentifier()) { + bool afterCXXScope = MaybeParseCXXScopeSpecifier(D.getCXXScopeSpec()); + if (afterCXXScope) { + // Change the declaration context for name lookup, until this function + // is exited (and the declarator has been parsed). + DeclScopeObj.EnterDeclaratorScope(); + } + + if (Tok.is(tok::identifier)) { + assert(Tok.getIdentifierInfo() && "Not an identifier?"); + // Determine whether this identifier is a C++ constructor name or + // a normal identifier. + if (Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope)) { + D.setConstructor(Actions.isTypeName(*Tok.getIdentifierInfo(), + CurScope), + Tok.getLocation()); + } else + D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); + ConsumeToken(); + goto PastIdentifier; + } + + if (Tok.is(tok::tilde)) { + // This should be a C++ destructor. + SourceLocation TildeLoc = ConsumeToken(); + if (Tok.is(tok::identifier)) { + if (TypeTy *Type = ParseClassName()) + D.setDestructor(Type, TildeLoc); + else + D.SetIdentifier(0, TildeLoc); + } else { + Diag(Tok, diag::err_expected_class_name); + D.SetIdentifier(0, TildeLoc); + } + goto PastIdentifier; + } + + // If we reached this point, token is not identifier and not '~'. + + if (afterCXXScope) { + Diag(Tok, diag::err_expected_unqualified_id); + D.SetIdentifier(0, Tok.getLocation()); + D.setInvalidType(true); + goto PastIdentifier; + } } - } else if (Tok.is(tok::kw_operator)) { - SourceLocation OperatorLoc = Tok.getLocation(); - // First try the name of an overloaded operator - if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) { - D.setOverloadedOperator(Op, OperatorLoc); - } else { - // This must be a conversion function (C++ [class.conv.fct]). - if (TypeTy *ConvType = ParseConversionFunctionId()) { - D.setConversionFunction(ConvType, OperatorLoc); + if (Tok.is(tok::kw_operator)) { + SourceLocation OperatorLoc = Tok.getLocation(); + + // First try the name of an overloaded operator + if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) { + D.setOverloadedOperator(Op, OperatorLoc); + } else { + // This must be a conversion function (C++ [class.conv.fct]). + if (TypeTy *ConvType = ParseConversionFunctionId()) + D.setConversionFunction(ConvType, OperatorLoc); + else + D.SetIdentifier(0, Tok.getLocation()); } + goto PastIdentifier; } - } else if (Tok.is(tok::l_paren) && SS.isEmpty()) { + } + + // If we reached this point, we are either in C/ObjC or the token didn't + // satisfy any of the C++-specific checks. + + if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) { + assert(!getLang().CPlusPlus && + "There's a C++-specific check for tok::identifier above"); + assert(Tok.getIdentifierInfo() && "Not an identifier?"); + D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); + ConsumeToken(); + } else if (Tok.is(tok::l_paren)) { // direct-declarator: '(' declarator ')' // direct-declarator: '(' attributes declarator ')' // Example: 'char (*X)' or 'int (*XX)(void)' ParseParenDeclarator(D); - } else if (D.mayOmitIdentifier() && SS.isEmpty()) { + } else if (D.mayOmitIdentifier()) { // This could be something simple like "int" (in which case the declarator // portion is empty), if an abstract-declarator is allowed. D.SetIdentifier(0, Tok.getLocation()); @@ -1496,6 +1525,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { D.setInvalidType(true); } + PastIdentifier: assert(D.isPastIdentifier() && "Haven't past the location of the identifier yet?"); -- 2.40.0