summaryrefslogtreecommitdiff
path: root/lib/Parse/Parser.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
commit486754660bb926339aefcf012a3f848592babb8b (patch)
treeecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Parse/Parser.cpp
parent55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff)
Notes
Diffstat (limited to 'lib/Parse/Parser.cpp')
-rw-r--r--lib/Parse/Parser.cpp81
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();