summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/tools/clang/lib/Parse/Parser.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2019-01-27 16:42:12 +0000
committerpatrick <patrick@openbsd.org>2019-01-27 16:42:12 +0000
commitb773203fb58f3ef282fb69c832d8710cab5bc82d (patch)
treee75913f147570fbd75169647b144df85b88a038c /gnu/llvm/tools/clang/lib/Parse/Parser.cpp
parenttweak errno in previous (diff)
downloadwireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz
wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Parse/Parser.cpp')
-rw-r--r--gnu/llvm/tools/clang/lib/Parse/Parser.cpp128
1 files changed, 67 insertions, 61 deletions
diff --git a/gnu/llvm/tools/clang/lib/Parse/Parser.cpp b/gnu/llvm/tools/clang/lib/Parse/Parser.cpp
index a6f966eda1b..c3085654f52 100644
--- a/gnu/llvm/tools/clang/lib/Parse/Parser.cpp
+++ b/gnu/llvm/tools/clang/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;
@@ -40,7 +41,7 @@ public:
} // end anonymous namespace
IdentifierInfo *Parser::getSEHExceptKeyword() {
- // __except is accepted as a (contextual) keyword
+ // __except is accepted as a (contextual) keyword
if (!Ident__except && (getLangOpts().MicrosoftExt || getLangOpts().Borland))
Ident__except = PP.getIdentifierInfo("__except");
@@ -49,7 +50,7 @@ IdentifierInfo *Parser::getSEHExceptKeyword() {
Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
: PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
- GreaterThanIsOperator(true), ColonIsSacred(false),
+ GreaterThanIsOperator(true), ColonIsSacred(false),
InMessageExpression(false), TemplateParameterDepth(0),
ParsingInObjCContainer(false) {
SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
@@ -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.
@@ -160,8 +161,8 @@ bool Parser::ExpectAndConsumeSemi(unsigned DiagID) {
handleUnexpectedCodeCompletionToken();
return false;
}
-
- if ((Tok.is(tok::r_paren) || Tok.is(tok::r_square)) &&
+
+ if ((Tok.is(tok::r_paren) || Tok.is(tok::r_square)) &&
NextToken().is(tok::semi)) {
Diag(Tok, diag::err_extraneous_token_before_semi)
<< PP.getSpelling(Tok)
@@ -170,7 +171,7 @@ bool Parser::ExpectAndConsumeSemi(unsigned DiagID) {
ConsumeToken(); // The ';'.
return false;
}
-
+
return ExpectAndConsume(tok::semi, DiagID);
}
@@ -290,7 +291,7 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
if (!HasFlagsSet(Flags, StopAtCodeCompletion))
handleUnexpectedCodeCompletionToken();
return false;
-
+
case tok::l_paren:
// Recursively skip properly-nested parens.
ConsumeParen();
@@ -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) {
@@ -796,17 +796,17 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs);
}
goto dont_know;
-
+
case tok::kw_inline:
if (getLangOpts().CPlusPlus) {
tok::TokenKind NextKind = NextToken().getKind();
-
+
// Inline namespaces. Allowed as an extension even in C++03.
if (NextKind == tok::kw_namespace) {
SourceLocation DeclEnd;
return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs);
}
-
+
// Parse (then ignore) 'inline' prior to a template instantiation. This is
// a GCC extension that we intentionally do not support.
if (NextKind == tok::kw_template) {
@@ -828,8 +828,8 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc);
SourceLocation DeclEnd;
return Actions.ConvertDeclToDeclGroup(
- ParseExplicitInstantiation(DeclaratorContext::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'
@@ -867,7 +867,7 @@ bool Parser::isDeclarationAfterDeclarator() {
if (KW.is(tok::kw_default) || KW.is(tok::kw_delete))
return false;
}
-
+
return Tok.is(tok::equal) || // int X()= -> not a function def
Tok.is(tok::comma) || // int X(), -> not a function def
Tok.is(tok::semi) || // int X(); -> not a function def
@@ -877,23 +877,23 @@ 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");
if (Tok.is(tok::l_brace)) // int X() {}
return true;
-
+
// Handle K&R C argument lists: int X(f) int f; {}
if (!getLangOpts().CPlusPlus &&
- Declarator.getFunctionTypeInfo().isKNRPrototype())
+ Declarator.getFunctionTypeInfo().isKNRPrototype())
return isDeclarationSpecifier();
if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) {
const Token &KW = NextToken();
return KW.is(tok::kw_default) || KW.is(tok::kw_delete);
}
-
+
return Tok.is(tok::colon) || // X() : Base() {} (used for ctors)
Tok.is(tok::kw_try); // X() try { ... }
}
@@ -947,7 +947,7 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
default:
llvm_unreachable("we only expect to get the length of the class/struct/union/enum");
}
-
+
};
// Suggest correct location to fix '[[attrib]] struct' to 'struct [[attrib]]'
SourceLocation CorrectLocationForAttributes =
@@ -1072,7 +1072,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// We should have either an opening brace or, in a C++ constructor,
// we may have a colon.
- if (Tok.isNot(tok::l_brace) &&
+ if (Tok.isNot(tok::l_brace) &&
(!getLangOpts().CPlusPlus ||
(Tok.isNot(tok::colon) && Tok.isNot(tok::kw_try) &&
Tok.isNot(tok::equal)))) {
@@ -1089,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
@@ -1133,10 +1128,10 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
}
return DP;
}
- else if (CurParsedObjCImpl &&
+ else if (CurParsedObjCImpl &&
!TemplateInfo.TemplateParams &&
(Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
- Tok.is(tok::colon)) &&
+ Tok.is(tok::colon)) &&
Actions.CurContext->isTranslationUnit()) {
ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
Scope::CompoundStmtScope);
@@ -1176,7 +1171,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// Break out of the ParsingDeclarator context before we parse the body.
D.complete(Res);
-
+
// Break out of the ParsingDeclSpec context, too. This const_cast is
// safe because we're always the sole owner.
D.getMutableDeclSpec().abort();
@@ -1451,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) {
@@ -1479,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.
@@ -1715,7 +1710,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() {
TypeResult Ty;
if (Tok.is(tok::identifier)) {
// FIXME: check whether the next token is '<', first!
- Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS,
+ Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS,
*Tok.getIdentifierInfo(),
Tok.getLocation());
} else if (Tok.is(tok::annot_template_id)) {
@@ -1764,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,
@@ -1775,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();
@@ -1931,14 +1926,14 @@ SourceLocation Parser::handleUnexpectedCodeCompletionToken() {
cutOffParsing();
return PrevTokLocation;
}
-
+
if (S->getFlags() & Scope::ClassScope) {
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class);
cutOffParsing();
return PrevTokLocation;
}
}
-
+
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace);
cutOffParsing();
return PrevTokLocation;
@@ -1958,7 +1953,7 @@ void Parser::CodeCompleteMacroName(bool IsDefinition) {
Actions.CodeCompletePreprocessorMacroName(IsDefinition);
}
-void Parser::CodeCompletePreprocessorExpression() {
+void Parser::CodeCompletePreprocessorExpression() {
Actions.CodeCompletePreprocessorExpression();
}
@@ -1981,11 +1976,11 @@ bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) {
BalancedDelimiterTracker T(*this, tok::l_paren);
if (T.consumeOpen()) {
- Diag(Tok, diag::err_expected_lparen_after)
+ Diag(Tok, diag::err_expected_lparen_after)
<< (Result.IsIfExists? "__if_exists" : "__if_not_exists");
return true;
}
-
+
// Parse nested-name-specifier.
if (getLangOpts().CPlusPlus)
ParseOptionalCXXScopeSpecifier(Result.SS, nullptr,
@@ -2002,14 +1997,14 @@ 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;
}
if (T.consumeClose())
return true;
-
+
// Check if the symbol exists.
switch (Actions.CheckMicrosoftIfExistsSymbol(getCurScope(), Result.KeywordLoc,
Result.IsIfExists, Result.SS,
@@ -2025,7 +2020,7 @@ bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) {
case Sema::IER_Dependent:
Result.Behavior = IEB_Dependent;
break;
-
+
case Sema::IER_Error:
return true;
}
@@ -2037,7 +2032,7 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
IfExistsCondition Result;
if (ParseMicrosoftIfExistsCondition(Result))
return;
-
+
BalancedDelimiterTracker Braces(*this, tok::l_brace);
if (Braces.consumeOpen()) {
Diag(Tok, diag::err_expected) << tok::l_brace;
@@ -2048,10 +2043,10 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
case IEB_Parse:
// Parse declarations below.
break;
-
+
case IEB_Dependent:
llvm_unreachable("Cannot have a dependent external declaration");
-
+
case IEB_Skip:
Braces.skipToEnd();
return;
@@ -2114,7 +2109,7 @@ Parser::DeclGroupPtrTy Parser::ParseModuleDecl() {
/// Parse a module import declaration. This is essentially the same for
/// Objective-C and the C++ Modules TS, except for the leading '@' (in ObjC)
/// and the trailing optional attributes (in C++).
-///
+///
/// [ObjC] @import declaration:
/// '@' 'import' module-name ';'
/// [ModTS] module-import-declaration:
@@ -2123,9 +2118,10 @@ 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;
-
+
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
if (ParseModuleName(ImportLoc, Path, /*IsImport*/true))
return nullptr;
@@ -2146,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();
}
@@ -2168,12 +2174,12 @@ bool Parser::ParseModuleName(
cutOffParsing();
return true;
}
-
+
Diag(Tok, diag::err_module_expected_ident) << IsImport;
SkipUntil(tok::semi);
return true;
}
-
+
// Record this part of the module path.
Path.push_back(std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation()));
ConsumeToken();
@@ -2185,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.
@@ -2250,9 +2256,9 @@ bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
return true;
}
- if (getDepth() < MaxDepth)
+ if (getDepth() < P.getLangOpts().BracketDepth)
return false;
-
+
return diagnoseOverflow();
}