diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
| commit | 486754660bb926339aefcf012a3f848592babb8b (patch) | |
| tree | ecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Parse/Parser.cpp | |
| parent | 55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff) | |
Notes
Diffstat (limited to 'lib/Parse/Parser.cpp')
| -rw-r--r-- | lib/Parse/Parser.cpp | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 8aa50a2c7f2a..7a0b29cbae86 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -20,11 +20,12 @@ #include "clang/Sema/DeclSpec.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" +#include "llvm/Support/Path.h" using namespace clang; namespace { -/// \brief A comment handler that passes comments found by the preprocessor +/// A comment handler that passes comments found by the preprocessor /// to the parser action. class ActionCommentHandler : public CommentHandler { Sema &S; @@ -77,7 +78,7 @@ DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) { return Diag(Tok.getLocation(), DiagID); } -/// \brief Emits a diagnostic suggesting parentheses surrounding a +/// Emits a diagnostic suggesting parentheses surrounding a /// given range. /// /// \param Loc The location where we'll emit the diagnostic. @@ -697,9 +698,8 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, return nullptr; case tok::semi: // Either a C++11 empty-declaration or attribute-declaration. - SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(), - attrs.getList(), - Tok.getLocation()); + SingleDecl = + Actions.ActOnEmptyDeclaration(getCurScope(), attrs, Tok.getLocation()); ConsumeExtraSemi(OutsideFunction); break; case tok::r_brace: @@ -741,7 +741,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, break; } case tok::at: - return ParseObjCAtDirectives(); + return ParseObjCAtDirectives(attrs); case tok::minus: case tok::plus: if (!getLangOpts().ObjC1) { @@ -783,7 +783,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, // A function definition cannot start with any of these keywords. { SourceLocation DeclEnd; - return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs); + return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs); } case tok::kw_static: @@ -793,7 +793,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored) << 0; SourceLocation DeclEnd; - return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs); + return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs); } goto dont_know; @@ -804,7 +804,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, // Inline namespaces. Allowed as an extension even in C++03. if (NextKind == tok::kw_namespace) { SourceLocation DeclEnd; - return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs); + return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs); } // Parse (then ignore) 'inline' prior to a template instantiation. This is @@ -813,7 +813,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored) << 1; SourceLocation DeclEnd; - return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs); + return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs); } } goto dont_know; @@ -828,8 +828,8 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc); SourceLocation DeclEnd; return Actions.ConvertDeclToDeclGroup( - ParseExplicitInstantiation(Declarator::FileContext, - ExternLoc, TemplateLoc, DeclEnd)); + ParseExplicitInstantiation(DeclaratorContext::FileContext, ExternLoc, + TemplateLoc, DeclEnd, attrs)); } goto dont_know; @@ -858,7 +858,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, return Actions.ConvertDeclToDeclGroup(SingleDecl); } -/// \brief Determine whether the current token, if it occurs after a +/// Determine whether the current token, if it occurs after a /// declarator, continues a declaration or declaration list. bool Parser::isDeclarationAfterDeclarator() { // Check for '= delete' or '= default' @@ -877,7 +877,7 @@ bool Parser::isDeclarationAfterDeclarator() { Tok.is(tok::l_paren)); // int X(0) -> not a function def [C++] } -/// \brief Determine whether the current token, if it occurs after a +/// Determine whether the current token, if it occurs after a /// declarator, indicates the start of a function definition. bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) { assert(Declarator.isFunctionDeclarator() && "Isn't a function declarator"); @@ -919,12 +919,13 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs, AccessSpecifier AS) { MaybeParseMicrosoftAttributes(DS.getAttributes()); // Parse the common declaration-specifiers piece. - ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level); + ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, + DeclSpecContext::DSC_top_level); // If we had a free-standing type definition with a missing semicolon, we // may get this far before the problem becomes obvious. - if (DS.hasTagDefinition() && - DiagnoseMissingSemiAfterTagDefinition(DS, AS, DSC_top_level)) + if (DS.hasTagDefinition() && DiagnoseMissingSemiAfterTagDefinition( + DS, AS, DeclSpecContext::DSC_top_level)) return nullptr; // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" @@ -1004,11 +1005,11 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs, if (getLangOpts().CPlusPlus && isTokenStringLiteral() && DS.getStorageClassSpec() == DeclSpec::SCS_extern && DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) { - Decl *TheDecl = ParseLinkage(DS, Declarator::FileContext); + Decl *TheDecl = ParseLinkage(DS, DeclaratorContext::FileContext); return Actions.ConvertDeclToDeclGroup(TheDecl); } - return ParseDeclGroup(DS, Declarator::FileContext); + return ParseDeclGroup(DS, DeclaratorContext::FileContext); } Parser::DeclGroupPtrTy @@ -1088,15 +1089,10 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, // Check to make sure that any normal attributes are allowed to be on // a definition. Late parsed attributes are checked at the end. if (Tok.isNot(tok::equal)) { - AttributeList *DtorAttrs = D.getAttributes(); - while (DtorAttrs) { - if (DtorAttrs->isKnownToGCC() && - !DtorAttrs->isCXX11Attribute()) { - Diag(DtorAttrs->getLoc(), diag::warn_attribute_on_function_definition) - << DtorAttrs->getName(); - } - DtorAttrs = DtorAttrs->getNext(); - } + for (const ParsedAttr &AL : D.getAttributes()) + if (AL.isKnownToGCC() && !AL.isCXX11Attribute()) + Diag(AL.getLoc(), diag::warn_attribute_on_function_definition) + << AL.getName(); } // In delayed template parsing mode, for function template we consume the @@ -1313,7 +1309,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { } // Parse the first declarator attached to this declspec. - Declarator ParmDeclarator(DS, Declarator::KNRTypeListContext); + Declarator ParmDeclarator(DS, DeclaratorContext::KNRTypeListContext); ParseDeclarator(ParmDeclarator); // Handle the full declarator list. @@ -1450,7 +1446,7 @@ ExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) { return Result; } -/// \brief Get the TemplateIdAnnotation from the token and put it in the +/// Get the TemplateIdAnnotation from the token and put it in the /// cleanup pool so that it gets destroyed when parsing the current top level /// declaration is finished. TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) { @@ -1478,7 +1474,7 @@ void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) { PP.AnnotateCachedTokens(Tok); } -/// \brief Attempt to classify the name at the current token position. This may +/// Attempt to classify the name at the current token position. This may /// form a type, scope or primary expression annotation, or replace the token /// with a typo-corrected keyword. This is only appropriate when the current /// name must refer to an entity which has already been declared. @@ -1763,7 +1759,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() { return TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation); } -/// \brief Try to annotate a type or scope token, having already parsed an +/// Try to annotate a type or scope token, having already parsed an /// optional scope specifier. \p IsNewScope should be \c true unless the scope /// specifier was extracted from an existing tok::annot_cxxscope annotation. bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS, @@ -1774,8 +1770,8 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS, *Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), &SS, false, NextToken().is(tok::period), nullptr, /*IsCtorOrDtorName=*/false, - /*NonTrivialTypeSourceInfo*/ true, - /*IsClassTemplateDeductionContext*/GreaterThanIsOperator)) { + /*NonTrivialTypeSourceInfo*/true, + /*IsClassTemplateDeductionContext*/true)) { SourceLocation BeginLoc = Tok.getLocation(); if (SS.isNotEmpty()) // it was a C++ qualified type name. BeginLoc = SS.getBeginLoc(); @@ -2001,7 +1997,7 @@ bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) { if (ParseUnqualifiedId( Result.SS, /*EnteringContext*/false, /*AllowDestructorName*/true, /*AllowConstructorName*/true, /*AllowDeductionGuide*/false, nullptr, - TemplateKWLoc, Result.Name)) { + &TemplateKWLoc, Result.Name)) { T.skipToEnd(); return true; } @@ -2122,6 +2118,7 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc) { assert((AtLoc.isInvalid() ? Tok.is(tok::kw_import) : Tok.isObjCAtKeyword(tok::objc_import)) && "Improper start to module import"); + bool IsObjCAtImport = Tok.isObjCAtKeyword(tok::objc_import); SourceLocation ImportLoc = ConsumeToken(); SourceLocation StartLoc = AtLoc.isInvalid() ? ImportLoc : AtLoc; @@ -2145,6 +2142,16 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc) { if (Import.isInvalid()) return nullptr; + // Using '@import' in framework headers requires modules to be enabled so that + // the header is parseable. Emit a warning to make the user aware. + if (IsObjCAtImport && AtLoc.isValid()) { + auto &SrcMgr = PP.getSourceManager(); + auto *FE = SrcMgr.getFileEntryForID(SrcMgr.getFileID(AtLoc)); + if (FE && llvm::sys::path::parent_path(FE->getDir()->getName()) + .endswith(".framework")) + Diags.Report(AtLoc, diag::warn_atimport_in_framework_header); + } + return Import.get(); } @@ -2184,7 +2191,7 @@ bool Parser::ParseModuleName( } } -/// \brief Try recover parser when module annotation appears where it must not +/// Try recover parser when module annotation appears where it must not /// be found. /// \returns false if the recover was successful and parsing may be continued, or /// true if parser must bail out to top level and handle the token there. @@ -2249,7 +2256,7 @@ bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID, return true; } - if (getDepth() < MaxDepth) + if (getDepth() < P.getLangOpts().BracketDepth) return false; return diagnoseOverflow(); |
