summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Parse
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse')
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp54
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp268
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp272
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp104
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp65
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseInit.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseObjc.cpp11
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseOpenMP.cpp11
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp50
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp53
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseStmtAsm.cpp12
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/Parser.cpp70
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/RAIIObjectsForParser.h22
14 files changed, 720 insertions, 278 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 59b491a..5da70d0 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -26,8 +26,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
AttributeList *AccessAttrs,
ParsingDeclarator &D,
const ParsedTemplateInfo &TemplateInfo,
- const VirtSpecifiers& VS,
- FunctionDefinitionKind DefinitionKind,
+ const VirtSpecifiers& VS,
ExprResult& Init) {
assert(D.isFunctionDeclarator() && "This isn't a function declarator!");
assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try) ||
@@ -40,7 +39,6 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
NamedDecl *FnD;
- D.setFunctionDefinitionKind(DefinitionKind);
if (D.getDeclSpec().isFriendSpecified())
FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D,
TemplateParams);
@@ -71,17 +69,24 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
bool Delete = false;
SourceLocation KWLoc;
+ SourceLocation KWEndLoc = Tok.getEndLoc().getLocWithOffset(-1);
if (TryConsumeToken(tok::kw_delete, KWLoc)) {
Diag(KWLoc, getLangOpts().CPlusPlus11
? diag::warn_cxx98_compat_deleted_function
: diag::ext_deleted_function);
Actions.SetDeclDeleted(FnD, KWLoc);
Delete = true;
+ if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) {
+ DeclAsFunction->setRangeEnd(KWEndLoc);
+ }
} else if (TryConsumeToken(tok::kw_default, KWLoc)) {
Diag(KWLoc, getLangOpts().CPlusPlus11
? diag::warn_cxx98_compat_defaulted_function
: diag::ext_defaulted_function);
Actions.SetDeclDefaulted(FnD, KWLoc);
+ if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) {
+ DeclAsFunction->setRangeEnd(KWEndLoc);
+ }
} else {
llvm_unreachable("function definition after = not 'delete' or 'default'");
}
@@ -97,12 +102,12 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
return FnD;
}
-
+
// In delayed template parsing mode, if we are within a class template
// or if we are about to parse function member template then consume
// the tokens and store them for parsing at the end of the translation unit.
if (getLangOpts().DelayedTemplateParsing &&
- DefinitionKind == FDK_Definition &&
+ D.getFunctionDefinitionKind() == FDK_Definition &&
!D.getDeclSpec().isConstexprSpecified() &&
!(FnD && FnD->getAsFunction() &&
FnD->getAsFunction()->getReturnType()->getContainedAutoType()) &&
@@ -306,9 +311,10 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope |
Scope::FunctionDeclarationScope | Scope::DeclScope);
for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
+ auto Param = cast<ParmVarDecl>(LM.DefaultArgs[I].Param);
// Introduce the parameter into scope.
- Actions.ActOnDelayedCXXMethodParameter(getCurScope(),
- LM.DefaultArgs[I].Param);
+ bool HasUnparsed = Param->hasUnparsedDefaultArg();
+ Actions.ActOnDelayedCXXMethodParameter(getCurScope(), Param);
if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
// Mark the end of the default argument so that we know when to stop when
// we parse it later on.
@@ -316,9 +322,8 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
Token DefArgEnd;
DefArgEnd.startToken();
DefArgEnd.setKind(tok::eof);
- DefArgEnd.setLocation(LastDefaultArgToken.getLocation().getLocWithOffset(
- LastDefaultArgToken.getLength()));
- DefArgEnd.setEofData(LM.DefaultArgs[I].Param);
+ DefArgEnd.setLocation(LastDefaultArgToken.getEndLoc());
+ DefArgEnd.setEofData(Param);
Toks->push_back(DefArgEnd);
// Parse the default argument from its saved token stream.
@@ -336,7 +341,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
// used.
EnterExpressionEvaluationContext Eval(Actions,
Sema::PotentiallyEvaluatedIfUsed,
- LM.DefaultArgs[I].Param);
+ Param);
ExprResult DefArgResult;
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
@@ -346,11 +351,9 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
DefArgResult = ParseAssignmentExpression();
DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult);
if (DefArgResult.isInvalid()) {
- Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param,
- EqualLoc);
+ Actions.ActOnParamDefaultArgumentError(Param, EqualLoc);
} else {
- if (Tok.isNot(tok::eof) ||
- Tok.getEofData() != LM.DefaultArgs[I].Param) {
+ if (Tok.isNot(tok::eof) || Tok.getEofData() != Param) {
// The last two tokens are the terminator and the saved value of
// Tok; the last token in the default argument is the one before
// those.
@@ -359,7 +362,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
<< SourceRange(Tok.getLocation(),
(*Toks)[Toks->size() - 3].getLocation());
}
- Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
+ Actions.ActOnParamDefaultArgument(Param, EqualLoc,
DefArgResult.get());
}
@@ -368,11 +371,21 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
while (Tok.isNot(tok::eof))
ConsumeAnyToken();
- if (Tok.is(tok::eof) && Tok.getEofData() == LM.DefaultArgs[I].Param)
+ if (Tok.is(tok::eof) && Tok.getEofData() == Param)
ConsumeAnyToken();
delete Toks;
LM.DefaultArgs[I].Toks = nullptr;
+ } else if (HasUnparsed) {
+ assert(Param->hasInheritedDefaultArg());
+ FunctionDecl *Old = cast<FunctionDecl>(LM.Method)->getPreviousDecl();
+ ParmVarDecl *OldParam = Old->getParamDecl(I);
+ assert (!OldParam->hasUnparsedDefaultArg());
+ if (OldParam->hasUninstantiatedDefaultArg())
+ Param->setUninstantiatedDefaultArg(
+ Param->getUninstantiatedDefaultArg());
+ else
+ Param->setDefaultArg(OldParam->getInit());
}
}
@@ -383,9 +396,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
Token ExceptionSpecEnd;
ExceptionSpecEnd.startToken();
ExceptionSpecEnd.setKind(tok::eof);
- ExceptionSpecEnd.setLocation(
- LastExceptionSpecToken.getLocation().getLocWithOffset(
- LastExceptionSpecToken.getLength()));
+ ExceptionSpecEnd.setLocation(LastExceptionSpecToken.getEndLoc());
ExceptionSpecEnd.setEofData(LM.Method);
Toks->push_back(ExceptionSpecEnd);
@@ -490,8 +501,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
Token BodyEnd;
BodyEnd.startToken();
BodyEnd.setKind(tok::eof);
- BodyEnd.setLocation(
- LastBodyToken.getLocation().getLocWithOffset(LastBodyToken.getLength()));
+ BodyEnd.setLocation(LastBodyToken.getEndLoc());
BodyEnd.setEofData(LM.D);
LM.Toks.push_back(BodyEnd);
// Append the current token at the end of the new token stream so that it
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp
index 4d05e16..bd114d7 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp
@@ -529,64 +529,72 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
/// [MS] extended-decl-modifier-seq:
/// extended-decl-modifier[opt]
/// extended-decl-modifier extended-decl-modifier-seq
-void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) {
+void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
+ SourceLocation *End) {
+ assert((getLangOpts().MicrosoftExt || getLangOpts().Borland ||
+ getLangOpts().CUDA) &&
+ "Incorrect language options for parsing __declspec");
assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
- ConsumeToken();
- BalancedDelimiterTracker T(*this, tok::l_paren);
- if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",
- tok::r_paren))
- return;
-
- // An empty declspec is perfectly legal and should not warn. Additionally,
- // you can specify multiple attributes per declspec.
- while (Tok.isNot(tok::r_paren)) {
- // Attribute not present.
- if (TryConsumeToken(tok::comma))
- continue;
-
- // We expect either a well-known identifier or a generic string. Anything
- // else is a malformed declspec.
- bool IsString = Tok.getKind() == tok::string_literal ? true : false;
- if (!IsString && Tok.getKind() != tok::identifier &&
- Tok.getKind() != tok::kw_restrict) {
- Diag(Tok, diag::err_ms_declspec_type);
- T.skipToEnd();
+ while (Tok.is(tok::kw___declspec)) {
+ ConsumeToken();
+ BalancedDelimiterTracker T(*this, tok::l_paren);
+ if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",
+ tok::r_paren))
return;
- }
- IdentifierInfo *AttrName;
- SourceLocation AttrNameLoc;
- if (IsString) {
- SmallString<8> StrBuffer;
- bool Invalid = false;
- StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
- if (Invalid) {
+ // An empty declspec is perfectly legal and should not warn. Additionally,
+ // you can specify multiple attributes per declspec.
+ while (Tok.isNot(tok::r_paren)) {
+ // Attribute not present.
+ if (TryConsumeToken(tok::comma))
+ continue;
+
+ // We expect either a well-known identifier or a generic string. Anything
+ // else is a malformed declspec.
+ bool IsString = Tok.getKind() == tok::string_literal;
+ if (!IsString && Tok.getKind() != tok::identifier &&
+ Tok.getKind() != tok::kw_restrict) {
+ Diag(Tok, diag::err_ms_declspec_type);
T.skipToEnd();
return;
}
- AttrName = PP.getIdentifierInfo(Str);
- AttrNameLoc = ConsumeStringToken();
- } else {
- AttrName = Tok.getIdentifierInfo();
- AttrNameLoc = ConsumeToken();
- }
- bool AttrHandled = false;
+ IdentifierInfo *AttrName;
+ SourceLocation AttrNameLoc;
+ if (IsString) {
+ SmallString<8> StrBuffer;
+ bool Invalid = false;
+ StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
+ if (Invalid) {
+ T.skipToEnd();
+ return;
+ }
+ AttrName = PP.getIdentifierInfo(Str);
+ AttrNameLoc = ConsumeStringToken();
+ } else {
+ AttrName = Tok.getIdentifierInfo();
+ AttrNameLoc = ConsumeToken();
+ }
+
+ bool AttrHandled = false;
- // Parse attribute arguments.
- if (Tok.is(tok::l_paren))
- AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
- else if (AttrName->getName() == "property")
- // The property attribute must have an argument list.
- Diag(Tok.getLocation(), diag::err_expected_lparen_after)
- << AttrName->getName();
+ // Parse attribute arguments.
+ if (Tok.is(tok::l_paren))
+ AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
+ else if (AttrName->getName() == "property")
+ // The property attribute must have an argument list.
+ Diag(Tok.getLocation(), diag::err_expected_lparen_after)
+ << AttrName->getName();
- if (!AttrHandled)
- Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- AttributeList::AS_Declspec);
+ if (!AttrHandled)
+ Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
+ AttributeList::AS_Declspec);
+ }
+ T.consumeClose();
+ if (End)
+ *End = T.getCloseLocation();
}
- T.consumeClose();
}
void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
@@ -1360,6 +1368,46 @@ void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs) {
}
}
+// As an exception to the rule, __declspec(align(...)) before the
+// class-key affects the type instead of the variable.
+void Parser::handleDeclspecAlignBeforeClassKey(ParsedAttributesWithRange &Attrs,
+ DeclSpec &DS,
+ Sema::TagUseKind TUK) {
+ if (TUK == Sema::TUK_Reference)
+ return;
+
+ ParsedAttributes &PA = DS.getAttributes();
+ AttributeList *AL = PA.getList();
+ AttributeList *Prev = nullptr;
+ while (AL) {
+ AttributeList *Next = AL->getNext();
+
+ // We only consider attributes using the appropriate '__declspec' spelling,
+ // this behavior doesn't extend to any other spellings.
+ if (AL->getKind() == AttributeList::AT_Aligned &&
+ AL->isDeclspecAttribute()) {
+ // Stitch the attribute into the tag's attribute list.
+ AL->setNext(nullptr);
+ Attrs.add(AL);
+
+ // Remove the attribute from the variable's attribute list.
+ if (Prev) {
+ // Set the last variable attribute's next attribute to be the attribute
+ // after the current one.
+ Prev->setNext(Next);
+ } else {
+ // Removing the head of the list requires us to reset the head to the
+ // next attribute.
+ PA.set(Next);
+ }
+ } else {
+ Prev = AL;
+ }
+
+ AL = Next;
+ }
+}
+
/// ParseDeclaration - Parse a full 'declaration', which consists of
/// declaration-specifiers, some number of declarators, and a semicolon.
/// 'Context' should be a Declarator::TheContext value. This returns the
@@ -1691,11 +1739,12 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
}
if (isDeclarationSpecifier()) {
- // If there is an invalid declaration specifier right after the function
- // prototype, then we must be in a missing semicolon case where this isn't
- // actually a body. Just fall through into the code that handles it as a
- // prototype, and let the top-level code handle the erroneous declspec
- // where it would otherwise expect a comma or semicolon.
+ // If there is an invalid declaration specifier right after the
+ // function prototype, then we must be in a missing semicolon case
+ // where this isn't actually a body. Just fall through into the code
+ // that handles it as a prototype, and let the top-level code handle
+ // the erroneous declspec where it would otherwise expect a comma or
+ // semicolon.
} else {
Diag(Tok, diag::err_expected_fn_body);
SkipUntil(tok::semi);
@@ -1993,7 +2042,11 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
}
- if (ParseExpressionList(Exprs, CommaLocs)) {
+ if (ParseExpressionList(Exprs, CommaLocs, [&] {
+ Actions.CodeCompleteConstructor(getCurScope(),
+ cast<VarDecl>(ThisDecl)->getType()->getCanonicalTypeInternal(),
+ ThisDecl->getLocation(), Exprs);
+ })) {
Actions.ActOnInitializerError(ThisDecl);
SkipUntil(tok::r_paren, StopAtSemi);
@@ -2564,7 +2617,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
bool AttrsLastTime = false;
ParsedAttributesWithRange attrs(AttrFactory);
- const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
+ // We use Sema's policy to get bool macros right.
+ const PrintingPolicy &Policy = Actions.getPrintingPolicy();
while (1) {
bool isInvalid = false;
bool isStorageClass = false;
@@ -2871,9 +2925,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Tok.getLocation(), getCurScope());
// MSVC: If we weren't able to parse a default template argument, and it's
- // just a simple identifier, create a DependentNameType. This will allow us
- // to defer the name lookup to template instantiation time, as long we forge a
- // NestedNameSpecifier for the current context.
+ // just a simple identifier, create a DependentNameType. This will allow
+ // us to defer the name lookup to template instantiation time, as long we
+ // forge a NestedNameSpecifier for the current context.
if (!TypeRep && DSContext == DSC_template_type_arg &&
getLangOpts().MSVCCompat && getCurScope()->isTemplateParamScope()) {
TypeRep = Actions.ActOnDelayedDefaultTemplateArg(
@@ -2950,7 +3004,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// Microsoft declspec support.
case tok::kw___declspec:
- ParseMicrosoftDeclSpec(DS.getAttributes());
+ ParseMicrosoftDeclSpecs(DS.getAttributes());
continue;
// Microsoft single token adornments.
@@ -3594,10 +3648,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseGNUAttributes(attrs);
MaybeParseCXX11Attributes(attrs);
-
- // If declspecs exist after tag, parse them.
- while (Tok.is(tok::kw___declspec))
- ParseMicrosoftDeclSpec(attrs);
+ MaybeParseMicrosoftDeclSpecs(attrs);
SourceLocation ScopedEnumKWLoc;
bool IsScopedUsingClassTag = false;
@@ -3616,8 +3667,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// They are allowed afterwards, though.
MaybeParseGNUAttributes(attrs);
MaybeParseCXX11Attributes(attrs);
- while (Tok.is(tok::kw___declspec))
- ParseMicrosoftDeclSpec(attrs);
+ MaybeParseMicrosoftDeclSpecs(attrs);
}
// C++11 [temp.explicit]p12:
@@ -3644,11 +3694,12 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// if a fixed underlying type is allowed.
ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
- if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
+ CXXScopeSpec Spec;
+ if (ParseOptionalCXXScopeSpecifier(Spec, ParsedType(),
/*EnteringContext=*/true))
return;
- if (SS.isSet() && Tok.isNot(tok::identifier)) {
+ if (Spec.isSet() && Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected) << tok::identifier;
if (Tok.isNot(tok::l_brace)) {
// Has no name and is not a definition.
@@ -3657,6 +3708,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
return;
}
}
+
+ SS = Spec;
}
// Must have either 'enum name' or 'enum {...}'.
@@ -3842,6 +3895,15 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
return;
}
+ handleDeclspecAlignBeforeClassKey(attrs, DS, TUK);
+
+ Sema::SkipBodyInfo SkipBody;
+ if (!Name && TUK == Sema::TUK_Definition && Tok.is(tok::l_brace) &&
+ NextToken().is(tok::identifier))
+ SkipBody = Actions.shouldSkipAnonEnumBody(getCurScope(),
+ NextToken().getIdentifierInfo(),
+ NextToken().getLocation());
+
bool Owned = false;
bool IsDependent = false;
const char *PrevSpec = nullptr;
@@ -3851,7 +3913,22 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
AS, DS.getModulePrivateSpecLoc(), TParams,
Owned, IsDependent, ScopedEnumKWLoc,
IsScopedUsingClassTag, BaseType,
- DSC == DSC_type_specifier);
+ DSC == DSC_type_specifier, &SkipBody);
+
+ if (SkipBody.ShouldSkip) {
+ assert(TUK == Sema::TUK_Definition && "can only skip a definition");
+
+ BalancedDelimiterTracker T(*this, tok::l_brace);
+ T.consumeOpen();
+ T.skipToEnd();
+
+ if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
+ NameLoc.isValid() ? NameLoc : StartLoc,
+ PrevSpec, DiagID, TagDecl, Owned,
+ Actions.getASTContext().getPrintingPolicy()))
+ Diag(StartLoc, DiagID) << PrevSpec;
+ return;
+ }
if (IsDependent) {
// This enum has a dependent nested-name-specifier. Handle it as a
@@ -3923,6 +4000,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
Diag(Tok, diag::error_empty_enum);
SmallVector<Decl *, 32> EnumConstantDecls;
+ SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
Decl *LastEnumConstDecl = nullptr;
@@ -3953,7 +4031,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
SourceLocation EqualLoc;
ExprResult AssignedVal;
- ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
+ EnumAvailabilityDiags.emplace_back(*this);
if (TryConsumeToken(tok::equal, EqualLoc)) {
AssignedVal = ParseConstantExpression();
@@ -3967,7 +4045,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
IdentLoc, Ident,
attrs.getList(), EqualLoc,
AssignedVal.get());
- PD.complete(EnumConstDecl);
+ EnumAvailabilityDiags.back().done();
EnumConstantDecls.push_back(EnumConstDecl);
LastEnumConstDecl = EnumConstDecl;
@@ -4023,6 +4101,14 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
getCurScope(),
attrs.getList());
+ // Now handle enum constant availability diagnostics.
+ assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
+ for (size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
+ ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
+ EnumAvailabilityDiags[i].redelay();
+ PD.complete(EnumConstantDecls[i]);
+ }
+
EnumScope.Exit();
Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
T.getCloseLocation());
@@ -4773,7 +4859,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
DS.getConstSpecLoc(),
DS.getVolatileSpecLoc(),
- DS.getRestrictSpecLoc()),
+ DS.getRestrictSpecLoc(),
+ DS.getAtomicSpecLoc()),
DS.getAttributes(),
SourceLocation());
else
@@ -4916,7 +5003,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
}
if (D.getCXXScopeSpec().isValid()) {
- if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
+ if (Actions.ShouldEnterDeclaratorScope(getCurScope(),
+ D.getCXXScopeSpec()))
// Change the declaration context for name lookup, until this function
// is exited (and the declarator has been parsed).
DeclScopeObj.EnterDeclaratorScope();
@@ -4968,6 +5056,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
AllowConstructorName = (D.getContext() == Declarator::MemberContext);
SourceLocation TemplateKWLoc;
+ bool HadScope = D.getCXXScopeSpec().isValid();
if (ParseUnqualifiedId(D.getCXXScopeSpec(),
/*EnteringContext=*/true,
/*AllowDestructorName=*/true,
@@ -4981,6 +5070,13 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
D.SetIdentifier(nullptr, Tok.getLocation());
D.setInvalidType(true);
} else {
+ // ParseUnqualifiedId might have parsed a scope specifier during error
+ // recovery. If it did so, enter that scope.
+ if (!HadScope && D.getCXXScopeSpec().isValid() &&
+ Actions.ShouldEnterDeclaratorScope(getCurScope(),
+ D.getCXXScopeSpec()))
+ DeclScopeObj.EnterDeclaratorScope();
+
// Parsed the unqualified-id; update range information and move along.
if (D.getSourceRange().getBegin().isInvalid())
D.SetRangeBegin(D.getName().getSourceRange().getBegin());
@@ -5022,7 +5118,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
// If there was an error parsing parenthesized declarator, declarator
// scope may have been entered before. Don't do it again.
if (!D.isInvalidType() &&
- Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
+ Actions.ShouldEnterDeclaratorScope(getCurScope(),
+ D.getCXXScopeSpec()))
// Change the declaration context for name lookup, until this function
// is exited (and the declarator has been parsed).
DeclScopeObj.EnterDeclaratorScope();
@@ -5310,7 +5407,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
if (getLangOpts().CPlusPlus) {
// FIXME: Accept these components in any order, and produce fixits to
// correct the order if the user gets it wrong. Ideally we should deal
- // with the virt-specifier-seq and pure-specifier in the same way.
+ // with the pure-specifier in the same way.
// Parse cv-qualifier-seq[opt].
ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed,
@@ -5323,15 +5420,8 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
}
// Parse ref-qualifier[opt].
- if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
- Diag(Tok, getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_ref_qualifier :
- diag::ext_ref_qualifier);
-
- RefQualifierIsLValueRef = Tok.is(tok::amp);
- RefQualifierLoc = ConsumeToken();
+ if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
EndLoc = RefQualifierLoc;
- }
// C++11 [expr.prim.general]p3:
// If a declaration declares a member function or member function
@@ -5427,6 +5517,22 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
FnAttrs, EndLoc);
}
+/// ParseRefQualifier - Parses a member function ref-qualifier. Returns
+/// true if a ref-qualifier is found.
+bool Parser::ParseRefQualifier(bool &RefQualifierIsLValueRef,
+ SourceLocation &RefQualifierLoc) {
+ if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
+ Diag(Tok, getLangOpts().CPlusPlus11 ?
+ diag::warn_cxx98_compat_ref_qualifier :
+ diag::ext_ref_qualifier);
+
+ RefQualifierIsLValueRef = Tok.is(tok::amp);
+ RefQualifierLoc = ConsumeToken();
+ return true;
+ }
+ return false;
+}
+
/// isFunctionDeclaratorIdentifierList - This parameter list may have an
/// identifier list form for a K&R-style function: void foo(a,b,c)
///
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp
index 87d9909..53e4a41 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp
@@ -558,6 +558,7 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
// Maybe this is an alias-declaration.
TypeResult TypeAlias;
bool IsAliasDecl = Tok.is(tok::equal);
+ Decl *DeclFromDeclSpec = nullptr;
if (IsAliasDecl) {
// If we had any misplaced attributes from earlier, this is where they
// should have been written.
@@ -612,10 +613,12 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
<< FixItHint::CreateRemoval(SS.getRange());
- TypeAlias = ParseTypeName(nullptr, TemplateInfo.Kind ?
- Declarator::AliasTemplateContext :
- Declarator::AliasDeclContext, AS, OwnedType,
- &Attrs);
+ TypeAlias = ParseTypeName(nullptr, TemplateInfo.Kind
+ ? Declarator::AliasTemplateContext
+ : Declarator::AliasDeclContext,
+ AS, &DeclFromDeclSpec, &Attrs);
+ if (OwnedType)
+ *OwnedType = DeclFromDeclSpec;
} else {
// C++11 attributes are not allowed on a using-declaration, but GNU ones
// are.
@@ -664,7 +667,7 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
TemplateParams ? TemplateParams->size() : 0);
return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
UsingLoc, Name, Attrs.getList(),
- TypeAlias);
+ TypeAlias, DeclFromDeclSpec);
}
return Actions.ActOnUsingDeclaration(getCurScope(), AS,
@@ -796,7 +799,10 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
// The operand of the decltype specifier is an unevaluated operand.
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
nullptr,/*IsDecltype=*/true);
- Result = Actions.CorrectDelayedTyposInExpr(ParseExpression());
+ Result =
+ Actions.CorrectDelayedTyposInExpr(ParseExpression(), [](Expr *E) {
+ return E->hasPlaceholderType() ? ExprError() : E;
+ });
if (Result.isInvalid()) {
DS.SetTypeSpecError();
if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) {
@@ -1223,10 +1229,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
ParsedAttributesWithRange attrs(AttrFactory);
// If attributes exist after tag, parse them.
MaybeParseGNUAttributes(attrs);
-
- // If declspecs exist after tag, parse them.
- while (Tok.is(tok::kw___declspec))
- ParseMicrosoftDeclSpec(attrs);
+ MaybeParseMicrosoftDeclSpecs(attrs);
// Parse inheritance specifiers.
if (Tok.is(tok::kw___single_inheritance) ||
@@ -1310,11 +1313,19 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// is a base-specifier-list.
ColonProtectionRAIIObject X(*this);
- if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
+ CXXScopeSpec Spec;
+ bool HasValidSpec = true;
+ if (ParseOptionalCXXScopeSpecifier(Spec, ParsedType(), EnteringContext)) {
DS.SetTypeSpecError();
- if (SS.isSet())
- if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
+ HasValidSpec = false;
+ }
+ if (Spec.isSet())
+ if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) {
Diag(Tok, diag::err_expected) << tok::identifier;
+ HasValidSpec = false;
+ }
+ if (HasValidSpec)
+ SS = Spec;
}
TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
@@ -1539,6 +1550,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
TypeResult TypeResult = true; // invalid
bool Owned = false;
+ Sema::SkipBodyInfo SkipBody;
if (TemplateId) {
// Explicit specialization, class template partial specialization,
// or explicit instantiation.
@@ -1625,7 +1637,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
*TemplateId, attrs.getList(),
MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0]
: nullptr,
- TemplateParams ? TemplateParams->size() : 0));
+ TemplateParams ? TemplateParams->size() : 0),
+ &SkipBody);
}
} else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
TUK == Sema::TUK_Declaration) {
@@ -1677,6 +1690,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
TParams =
MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size());
+ handleDeclspecAlignBeforeClassKey(attrs, DS, TUK);
+
// Declaration or definition of a class type
TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
SS, Name, NameLoc, attrs.getList(), AS,
@@ -1684,7 +1699,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
TParams, Owned, IsDependent,
SourceLocation(), false,
clang::TypeResult(),
- DSC == DSC_type_specifier);
+ DSC == DSC_type_specifier,
+ &SkipBody);
// If ActOnTag said the type was dependent, try again with the
// less common call.
@@ -1700,7 +1716,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
assert(Tok.is(tok::l_brace) ||
(getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
isCXX11FinalKeyword());
- if (getLangOpts().CPlusPlus)
+ if (SkipBody.ShouldSkip)
+ SkipCXXMemberSpecification(StartLoc, AttrFixitLoc, TagType,
+ TagOrTempResult.get());
+ else if (getLangOpts().CPlusPlus)
ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType,
TagOrTempResult.get());
else
@@ -1882,51 +1901,40 @@ AccessSpecifier Parser::getAccessSpecifierIfPresent() const {
/// the class definition.
void Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
Decl *ThisDecl) {
- // We just declared a member function. If this member function
- // has any default arguments or an exception-specification, we'll need to
- // parse them later.
- LateParsedMethodDeclaration *LateMethod = nullptr;
DeclaratorChunk::FunctionTypeInfo &FTI
= DeclaratorInfo.getFunctionTypeInfo();
+ // If there was a late-parsed exception-specification, we'll need a
+ // late parse
+ bool NeedLateParse = FTI.getExceptionSpecType() == EST_Unparsed;
+
+ if (!NeedLateParse) {
+ // Look ahead to see if there are any default args
+ for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx) {
+ auto Param = cast<ParmVarDecl>(FTI.Params[ParamIdx].Param);
+ if (Param->hasUnparsedDefaultArg()) {
+ NeedLateParse = true;
+ break;
+ }
+ }
+ }
- // If there was a late-parsed exception-specification, hold onto its tokens.
- if (FTI.getExceptionSpecType() == EST_Unparsed) {
+ if (NeedLateParse) {
// Push this method onto the stack of late-parsed method
// declarations.
- LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
+ auto LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
- // Stash the exception-specification tokens in the late-pased mthod.
+ // Stash the exception-specification tokens in the late-pased method.
LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens;
FTI.ExceptionSpecTokens = 0;
- // Reserve space for the parameters.
+ // Push tokens for each parameter. Those that do not have
+ // defaults will be NULL.
LateMethod->DefaultArgs.reserve(FTI.NumParams);
- }
-
- for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx) {
- if (LateMethod || FTI.Params[ParamIdx].DefaultArgTokens) {
- if (!LateMethod) {
- // Push this method onto the stack of late-parsed method
- // declarations.
- LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
- getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
- LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
-
- // Add all of the parameters prior to this one (they don't
- // have default arguments).
- LateMethod->DefaultArgs.reserve(FTI.NumParams);
- for (unsigned I = 0; I < ParamIdx; ++I)
- LateMethod->DefaultArgs.push_back(
- LateParsedDefaultArgument(FTI.Params[I].Param));
- }
-
- // Add this parameter to the list of parameters (it may or may
- // not have a default argument).
+ for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx)
LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument(
- FTI.Params[ParamIdx].Param, FTI.Params[ParamIdx].DefaultArgTokens));
- }
+ FTI.Params[ParamIdx].Param, FTI.Params[ParamIdx].DefaultArgTokens));
}
}
@@ -2019,7 +2027,7 @@ bool Parser::isCXX11FinalKeyword() const {
/// \brief Parse a C++ member-declarator up to, but not including, the optional
/// brace-or-equal-initializer or pure-specifier.
-void Parser::ParseCXXMemberDeclaratorBeforeInitializer(
+bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
Declarator &DeclaratorInfo, VirtSpecifiers &VS, ExprResult &BitfieldSize,
LateParsedAttrList &LateParsedAttrs) {
// member-declarator:
@@ -2037,10 +2045,13 @@ void Parser::ParseCXXMemberDeclaratorBeforeInitializer(
BitfieldSize = ParseConstantExpression();
if (BitfieldSize.isInvalid())
SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
- } else
+ } else {
ParseOptionalCXX11VirtSpecifierSeq(
VS, getCurrentClass().IsInterface,
DeclaratorInfo.getDeclSpec().getFriendSpecLoc());
+ if (!VS.isUnset())
+ MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo, VS);
+ }
// If a simple-asm-expr is present, parse it.
if (Tok.is(tok::kw_asm)) {
@@ -2071,6 +2082,78 @@ void Parser::ParseCXXMemberDeclaratorBeforeInitializer(
Diag(Attr->getLoc(), diag::warn_gcc_attribute_location);
Attr = Attr->getNext();
}
+ MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo, VS);
+ }
+ }
+
+ // If this has neither a name nor a bit width, something has gone seriously
+ // wrong. Skip until the semi-colon or }.
+ if (!DeclaratorInfo.hasName() && BitfieldSize.isUnset()) {
+ // If so, skip until the semi-colon or a }.
+ SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
+ return true;
+ }
+ return false;
+}
+
+/// \brief Look for declaration specifiers possibly occurring after C++11
+/// virt-specifier-seq and diagnose them.
+void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
+ Declarator &D,
+ VirtSpecifiers &VS) {
+ DeclSpec DS(AttrFactory);
+
+ // GNU-style and C++11 attributes are not allowed here, but they will be
+ // handled by the caller. Diagnose everything else.
+ ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed, false);
+ D.ExtendWithDeclSpec(DS);
+
+ if (D.isFunctionDeclarator()) {
+ auto &Function = D.getFunctionTypeInfo();
+ if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
+ auto DeclSpecCheck = [&] (DeclSpec::TQ TypeQual,
+ const char *FixItName,
+ SourceLocation SpecLoc,
+ unsigned* QualifierLoc) {
+ FixItHint Insertion;
+ if (DS.getTypeQualifiers() & TypeQual) {
+ if (!(Function.TypeQuals & TypeQual)) {
+ std::string Name(FixItName);
+ Name += " ";
+ Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name.c_str());
+ Function.TypeQuals |= TypeQual;
+ *QualifierLoc = SpecLoc.getRawEncoding();
+ }
+ Diag(SpecLoc, diag::err_declspec_after_virtspec)
+ << FixItName
+ << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())
+ << FixItHint::CreateRemoval(SpecLoc)
+ << Insertion;
+ }
+ };
+ DeclSpecCheck(DeclSpec::TQ_const, "const", DS.getConstSpecLoc(),
+ &Function.ConstQualifierLoc);
+ DeclSpecCheck(DeclSpec::TQ_volatile, "volatile", DS.getVolatileSpecLoc(),
+ &Function.VolatileQualifierLoc);
+ DeclSpecCheck(DeclSpec::TQ_restrict, "restrict", DS.getRestrictSpecLoc(),
+ &Function.RestrictQualifierLoc);
+ }
+
+ // Parse ref-qualifiers.
+ bool RefQualifierIsLValueRef = true;
+ SourceLocation RefQualifierLoc;
+ if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {
+ const char *Name = (RefQualifierIsLValueRef ? "& " : "&& ");
+ FixItHint Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name);
+ Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef;
+ Function.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
+
+ Diag(RefQualifierLoc, diag::err_declspec_after_virtspec)
+ << (RefQualifierIsLValueRef ? "&" : "&&")
+ << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())
+ << FixItHint::CreateRemoval(RefQualifierLoc)
+ << Insertion;
+ D.SetRangeEnd(RefQualifierLoc);
}
}
}
@@ -2298,14 +2381,8 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
bool ExpectSemi = true;
// Parse the first declarator.
- ParseCXXMemberDeclaratorBeforeInitializer(DeclaratorInfo, VS, BitfieldSize,
- LateParsedAttrs);
-
- // If this has neither a name nor a bit width, something has gone seriously
- // wrong. Skip until the semi-colon or }.
- if (!DeclaratorInfo.hasName() && BitfieldSize.isUnset()) {
- // If so, skip until the semi-colon or a }.
- SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
+ if (ParseCXXMemberDeclaratorBeforeInitializer(
+ DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) {
TryConsumeToken(tok::semi);
return;
}
@@ -2344,6 +2421,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
DefinitionKind = FDK_Deleted;
}
}
+ DeclaratorInfo.setFunctionDefinitionKind(DefinitionKind);
// C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
// to a friend declaration, that declaration shall be a definition.
@@ -2354,7 +2432,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
ProhibitAttributes(FnAttrs);
}
- if (DefinitionKind) {
+ if (DefinitionKind != FDK_Declaration) {
if (!DeclaratorInfo.isFunctionDeclarator()) {
Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params);
ConsumeBrace();
@@ -2376,7 +2454,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
Decl *FunDecl =
ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo,
- VS, DefinitionKind, Init);
+ VS, Init);
if (FunDecl) {
for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
@@ -2530,16 +2608,17 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// Parse the next declarator.
DeclaratorInfo.clear();
VS.clear();
- BitfieldSize = true;
- Init = true;
+ BitfieldSize = ExprResult(/*Invalid=*/false);
+ Init = ExprResult(/*Invalid=*/false);
HasInitializer = false;
DeclaratorInfo.setCommaLoc(CommaLoc);
// GNU attributes are allowed before the second and subsequent declarator.
MaybeParseGNUAttributes(DeclaratorInfo);
- ParseCXXMemberDeclaratorBeforeInitializer(DeclaratorInfo, VS, BitfieldSize,
- LateParsedAttrs);
+ if (ParseCXXMemberDeclaratorBeforeInitializer(
+ DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs))
+ break;
}
if (ExpectSemi &&
@@ -2617,6 +2696,55 @@ ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
return ParseInitializer();
}
+void Parser::SkipCXXMemberSpecification(SourceLocation RecordLoc,
+ SourceLocation AttrFixitLoc,
+ unsigned TagType, Decl *TagDecl) {
+ // Skip the optional 'final' keyword.
+ if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
+ assert(isCXX11FinalKeyword() && "not a class definition");
+ ConsumeToken();
+
+ // Diagnose any C++11 attributes after 'final' keyword.
+ // We deliberately discard these attributes.
+ ParsedAttributesWithRange Attrs(AttrFactory);
+ CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
+
+ // This can only happen if we had malformed misplaced attributes;
+ // we only get called if there is a colon or left-brace after the
+ // attributes.
+ if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_brace))
+ return;
+ }
+
+ // Skip the base clauses. This requires actually parsing them, because
+ // otherwise we can't be sure where they end (a left brace may appear
+ // within a template argument).
+ if (Tok.is(tok::colon)) {
+ // Enter the scope of the class so that we can correctly parse its bases.
+ ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
+ ParsingClassDefinition ParsingDef(*this, TagDecl, /*NonNestedClass*/ true,
+ TagType == DeclSpec::TST_interface);
+ Actions.ActOnTagStartSkippedDefinition(getCurScope(), TagDecl);
+
+ // Parse the bases but don't attach them to the class.
+ ParseBaseClause(nullptr);
+
+ Actions.ActOnTagFinishSkippedDefinition();
+
+ if (!Tok.is(tok::l_brace)) {
+ Diag(PP.getLocForEndOfToken(PrevTokLocation),
+ diag::err_expected_lbrace_after_base_specifiers);
+ return;
+ }
+ }
+
+ // Skip the body.
+ assert(Tok.is(tok::l_brace));
+ BalancedDelimiterTracker T(*this, tok::l_brace);
+ T.consumeOpen();
+ T.skipToEnd();
+}
+
/// ParseCXXMemberSpecification - Parse the class definition.
///
/// member-specification:
@@ -2911,6 +3039,10 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
ParseLexedMemberInitializers(getCurrentClass());
ParseLexedMethodDefs(getCurrentClass());
PrevTokLocation = SavedPrevTokLocation;
+
+ // We've finished parsing everything, including default argument
+ // initializers.
+ Actions.ActOnFinishCXXMemberDefaultArgs(TagDecl);
}
if (TagDecl)
@@ -2965,9 +3097,11 @@ void Parser::DiagnoseUnexpectedNamespace(NamedDecl *D) {
/// mem-initializer ...[opt]
/// mem-initializer ...[opt] , mem-initializer-list
void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
- assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
+ assert(Tok.is(tok::colon) &&
+ "Constructor initializer always starts with ':'");
- // Poison the SEH identifiers so they are flagged as illegal in constructor initializers
+ // Poison the SEH identifiers so they are flagged as illegal in constructor
+ // initializers.
PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
SourceLocation ColonLoc = ConsumeToken();
@@ -3396,7 +3530,9 @@ IdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) {
// Alternative tokens do not have identifier info, but their spelling
// starts with an alphabetical character.
SmallString<8> SpellingBuf;
- StringRef Spelling = PP.getSpelling(Tok.getLocation(), SpellingBuf);
+ SourceLocation SpellingLoc =
+ PP.getSourceManager().getSpellingLoc(Tok.getLocation());
+ StringRef Spelling = PP.getSpelling(SpellingLoc, SpellingBuf);
if (isLetter(Spelling[0])) {
Loc = ConsumeToken();
return &PP.getIdentifierTable().get(Spelling);
@@ -3474,7 +3610,6 @@ bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
// The attribute was allowed to have arguments, but none were provided
// even though the attribute parsed successfully. This is an error.
Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
- return false;
} else if (!Attr->getMaxArgs()) {
// The attribute parsed successfully, but was not allowed to have any
// arguments. It doesn't matter whether any were provided -- the
@@ -3482,7 +3617,6 @@ bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
<< AttrName
<< FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));
- return false;
}
}
}
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp
index d0d97de..95a28a8 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp
@@ -347,7 +347,11 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
RHS = ParseCastExpression(false);
if (RHS.isInvalid()) {
+ // FIXME: Errors generated by the delayed typo correction should be
+ // printed before errors from parsing the RHS, not after.
Actions.CorrectDelayedTyposInExpr(LHS);
+ if (TernaryMiddle.isUsable())
+ TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
LHS = ExprError();
}
@@ -380,7 +384,11 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
RHSIsInitList = false;
if (RHS.isInvalid()) {
+ // FIXME: Errors generated by the delayed typo correction should be
+ // printed before errors from ParseRHSOfBinaryExpression, not after.
Actions.CorrectDelayedTyposInExpr(LHS);
+ if (TernaryMiddle.isUsable())
+ TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
LHS = ExprError();
}
@@ -446,8 +454,8 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
namespace {
class CastExpressionIdValidator : public CorrectionCandidateCallback {
public:
- CastExpressionIdValidator(bool AllowTypes, bool AllowNonTypes)
- : AllowNonTypes(AllowNonTypes) {
+ CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes)
+ : NextToken(Next), AllowNonTypes(AllowNonTypes) {
WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes;
}
@@ -458,11 +466,24 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
if (isa<TypeDecl>(ND))
return WantTypeSpecifiers;
- return AllowNonTypes &&
- CorrectionCandidateCallback::ValidateCandidate(candidate);
+
+ if (!AllowNonTypes || !CorrectionCandidateCallback::ValidateCandidate(candidate))
+ return false;
+
+ if (!(NextToken.is(tok::equal) || NextToken.is(tok::arrow) ||
+ NextToken.is(tok::period)))
+ return true;
+
+ for (auto *C : candidate) {
+ NamedDecl *ND = C->getUnderlyingDecl();
+ if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND))
+ return true;
+ }
+ return false;
}
private:
+ Token NextToken;
bool AllowNonTypes;
};
}
@@ -908,14 +929,20 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
SourceLocation TemplateKWLoc;
Token Replacement;
auto Validator = llvm::make_unique<CastExpressionIdValidator>(
- isTypeCast != NotTypeCast, isTypeCast != IsTypeCast);
+ Tok, isTypeCast != NotTypeCast, isTypeCast != IsTypeCast);
Validator->IsAddressOfOperand = isAddressOfOperand;
- Validator->WantRemainingKeywords = Tok.isNot(tok::r_paren);
+ if (Tok.is(tok::periodstar) || Tok.is(tok::arrowstar)) {
+ Validator->WantExpressionKeywords = false;
+ Validator->WantRemainingKeywords = false;
+ } else {
+ Validator->WantRemainingKeywords = Tok.isNot(tok::r_paren);
+ }
Name.setIdentifier(&II, ILoc);
Res = Actions.ActOnIdExpression(
getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren),
isAddressOfOperand, std::move(Validator),
- /*IsInlineAsmIdentifier=*/false, &Replacement);
+ /*IsInlineAsmIdentifier=*/false,
+ Tok.is(tok::r_paren) ? nullptr : &Replacement);
if (!Res.isInvalid() && !Res.get()) {
UnconsumeToken(Replacement);
return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
@@ -1441,10 +1468,14 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
if (OpKind == tok::l_paren || !LHS.isInvalid()) {
if (Tok.isNot(tok::r_paren)) {
- if (ParseExpressionList(ArgExprs, CommaLocs, &Sema::CodeCompleteCall,
- LHS.get())) {
+ if (ParseExpressionList(ArgExprs, CommaLocs, [&] {
+ Actions.CodeCompleteCall(getCurScope(), LHS.get(), ArgExprs);
+ })) {
(void)Actions.CorrectDelayedTyposInExpr(LHS);
LHS = ExprError();
+ } else if (LHS.isInvalid()) {
+ for (auto &E : ArgExprs)
+ Actions.CorrectDelayedTyposInExpr(E);
}
}
}
@@ -1453,7 +1484,19 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
if (LHS.isInvalid()) {
SkipUntil(tok::r_paren, StopAtSemi);
} else if (Tok.isNot(tok::r_paren)) {
- PT.consumeClose();
+ bool HadDelayedTypo = false;
+ if (Actions.CorrectDelayedTyposInExpr(LHS).get() != LHS.get())
+ HadDelayedTypo = true;
+ for (auto &E : ArgExprs)
+ if (Actions.CorrectDelayedTyposInExpr(E).get() != E)
+ HadDelayedTypo = true;
+ // If there were delayed typos in the LHS or ArgExprs, call SkipUntil
+ // instead of PT.consumeClose() to avoid emitting extra diagnostics for
+ // the unmatched l_paren.
+ if (HadDelayedTypo)
+ SkipUntil(tok::r_paren, StopAtSemi);
+ else
+ PT.consumeClose();
LHS = ExprError();
} else {
assert((ArgExprs.size() == 0 ||
@@ -1510,14 +1553,14 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
cutOffParsing();
return ExprError();
}
-
+
if (MayBePseudoDestructor && !LHS.isInvalid()) {
LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS,
ObjectType);
break;
}
- // Either the action has told is that this cannot be a
+ // Either the action has told us that this cannot be a
// pseudo-destructor expression (based on the type of base
// expression), or we didn't see a '~' in the right place. We
// can still parse a destructor name here, but in that case it
@@ -1526,7 +1569,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
// FIXME: Add support for explicit call of template constructor.
SourceLocation TemplateKWLoc;
UnqualifiedId Name;
- if (getLangOpts().ObjC2 && OpKind == tok::period && Tok.is(tok::kw_class)) {
+ if (getLangOpts().ObjC2 && OpKind == tok::period &&
+ Tok.is(tok::kw_class)) {
// Objective-C++:
// After a '.' in a member access expression, treat the keyword
// 'class' as if it were an identifier.
@@ -1551,8 +1595,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc,
OpKind, SS, TemplateKWLoc, Name,
CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
- : nullptr,
- Tok.is(tok::l_paren));
+ : nullptr);
break;
}
case tok::plusplus: // postfix-expression: postfix-expression '++'
@@ -2088,6 +2131,17 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) {
Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope));
} else {
+ // Find the nearest non-record decl context. Variables declared in a
+ // statement expression behave as if they were declared in the enclosing
+ // function, block, or other code construct.
+ DeclContext *CodeDC = Actions.CurContext;
+ while (CodeDC->isRecord() || isa<EnumDecl>(CodeDC)) {
+ CodeDC = CodeDC->getParent();
+ assert(CodeDC && !CodeDC->isFileContext() &&
+ "statement expr not in code context");
+ }
+ Sema::ContextRAII SavedContext(Actions, CodeDC, /*NewThisContext=*/false);
+
Actions.ActOnStartStmtExpr();
StmtResult Stmt(ParseCompoundStatement(true));
@@ -2256,6 +2310,11 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
InMessageExpressionRAIIObject InMessage(*this, false);
Result = ParseExpression(MaybeTypeCast);
+ if (!getLangOpts().CPlusPlus && MaybeTypeCast && Result.isUsable()) {
+ // Correct typos in non-C++ code earlier so that implicit-cast-like
+ // expressions are parsed correctly.
+ Result = Actions.CorrectDelayedTyposInExpr(Result);
+ }
ExprType = SimpleExpr;
if (isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis))
@@ -2354,7 +2413,8 @@ ExprResult Parser::ParseGenericSelectionExpression() {
// C11 6.5.1.1p3 "The controlling expression of a generic selection is
// not evaluated."
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
- ControllingExpr = ParseAssignmentExpression();
+ ControllingExpr =
+ Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
if (ControllingExpr.isInvalid()) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
@@ -2400,7 +2460,8 @@ ExprResult Parser::ParseGenericSelectionExpression() {
// FIXME: These expressions should be parsed in a potentially potentially
// evaluated context.
- ExprResult ER(ParseAssignmentExpression());
+ ExprResult ER(
+ Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
if (ER.isInvalid()) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
@@ -2493,17 +2554,14 @@ ExprResult Parser::ParseFoldExpression(ExprResult LHS,
/// [C++0x] assignment-expression
/// [C++0x] braced-init-list
/// \endverbatim
-bool Parser::ParseExpressionList(SmallVectorImpl<Expr*> &Exprs,
+bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
SmallVectorImpl<SourceLocation> &CommaLocs,
- void (Sema::*Completer)(Scope *S,
- Expr *Data,
- ArrayRef<Expr *> Args),
- Expr *Data) {
+ std::function<void()> Completer) {
bool SawError = false;
while (1) {
if (Tok.is(tok::code_completion)) {
if (Completer)
- (Actions.*Completer)(getCurScope(), Data, Exprs);
+ Completer();
else
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
cutOffParsing();
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp
index 67496ed..ed9f75d 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp
@@ -118,6 +118,7 @@ void Parser::CheckForLParenAfterColonColon() {
// Eat the '('.
ConsumeParen();
Token RParen;
+ RParen.setLocation(SourceLocation());
// Do we have a ')' ?
NextTok = StarTok.is(tok::star) ? GetLookAheadToken(2) : GetLookAheadToken(1);
if (NextTok.is(tok::r_paren)) {
@@ -194,6 +195,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
if (Tok.is(tok::annot_cxxscope)) {
assert(!LastII && "want last identifier but have already annotated scope");
+ assert(!MayBePseudoDestructor && "unexpected annot_cxxscope");
Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
Tok.getAnnotationRange(),
SS);
@@ -208,6 +210,13 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
SS = TemplateId->SS;
}
+ // Has to happen before any "return false"s in this function.
+ bool CheckForDestructor = false;
+ if (MayBePseudoDestructor && *MayBePseudoDestructor) {
+ CheckForDestructor = true;
+ *MayBePseudoDestructor = false;
+ }
+
if (LastII)
*LastII = nullptr;
@@ -244,12 +253,6 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
return Actions.ActOnSuperScopeSpecifier(SuperLoc, ConsumeToken(), SS);
}
- bool CheckForDestructor = false;
- if (MayBePseudoDestructor && *MayBePseudoDestructor) {
- CheckForDestructor = true;
- *MayBePseudoDestructor = false;
- }
-
if (!HasScopeSpecifier &&
(Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype))) {
DeclSpec DS(AttrFactory);
@@ -659,7 +662,8 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
Token Replacement;
- ExprResult Result = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
+ ExprResult Result =
+ tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);
if (Result.isUnset()) {
// If the ExprResult is valid but null, then typo correction suggested a
// keyword replacement that needs to be reparsed.
@@ -1090,6 +1094,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// compatible with GCC.
MaybeParseGNUAttributes(Attr, &DeclEndLoc);
+ // MSVC-style attributes must be parsed before the mutable specifier to be
+ // compatible with MSVC.
+ MaybeParseMicrosoftDeclSpecs(Attr, &DeclEndLoc);
+
// Parse 'mutable'[opt].
SourceLocation MutableLoc;
if (TryConsumeToken(tok::kw_mutable, MutableLoc))
@@ -1485,9 +1493,8 @@ Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
ParseDecltypeSpecifier(DS);
if (DS.getTypeSpecType() == TST_error)
return ExprError();
- return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc,
- OpKind, TildeLoc, DS,
- Tok.is(tok::l_paren));
+ return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind,
+ TildeLoc, DS);
}
if (!Tok.is(tok::identifier)) {
@@ -1510,11 +1517,9 @@ Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
/*AssumeTemplateName=*/true))
return ExprError();
- return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base,
- OpLoc, OpKind,
- SS, FirstTypeName, CCLoc,
- TildeLoc, SecondTypeName,
- Tok.is(tok::l_paren));
+ return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind,
+ SS, FirstTypeName, CCLoc, TildeLoc,
+ SecondTypeName);
}
/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
@@ -1602,7 +1607,11 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
CommaLocsTy CommaLocs;
if (Tok.isNot(tok::r_paren)) {
- if (ParseExpressionList(Exprs, CommaLocs)) {
+ if (ParseExpressionList(Exprs, CommaLocs, [&] {
+ Actions.CodeCompleteConstructor(getCurScope(),
+ TypeRep.get()->getCanonicalTypeInternal(),
+ DS.getLocEnd(), Exprs);
+ })) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
@@ -2509,14 +2518,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
}
// If the user wrote ~T::T, correct it to T::~T.
+ DeclaratorScopeObj DeclScopeObj(*this, SS);
if (!TemplateSpecified && NextToken().is(tok::coloncolon)) {
+ // Don't let ParseOptionalCXXScopeSpecifier() "correct"
+ // `int A; struct { ~A::A(); };` to `int A; struct { ~A:A(); };`,
+ // it will confuse this recovery logic.
+ ColonProtectionRAIIObject ColonRAII(*this, false);
+
if (SS.isSet()) {
AnnotateScopeToken(SS, /*NewAnnotation*/true);
SS.clear();
}
if (ParseOptionalCXXScopeSpecifier(SS, ObjectType, EnteringContext))
return true;
- if (Tok.isNot(tok::identifier) || NextToken().is(tok::coloncolon)) {
+ if (SS.isNotEmpty())
+ ObjectType = ParsedType();
+ if (Tok.isNot(tok::identifier) || NextToken().is(tok::coloncolon) ||
+ !SS.isSet()) {
Diag(TildeLoc, diag::err_destructor_tilde_scope);
return true;
}
@@ -2525,6 +2543,10 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
Diag(TildeLoc, diag::err_destructor_tilde_scope)
<< FixItHint::CreateRemoval(TildeLoc)
<< FixItHint::CreateInsertion(Tok.getLocation(), "~");
+
+ // Temporarily enter the scope for the rest of this function.
+ if (Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
+ DeclScopeObj.EnterDeclaratorScope();
}
// Parse the class-name (or template-name in a simple-template-id).
@@ -2668,7 +2690,14 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
ConstructorLParen = T.getOpenLocation();
if (Tok.isNot(tok::r_paren)) {
CommaLocsTy CommaLocs;
- if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
+ if (ParseExpressionList(ConstructorArgs, CommaLocs, [&] {
+ ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(),
+ DeclaratorInfo).get();
+ Actions.CodeCompleteConstructor(getCurScope(),
+ TypeRep.get()->getCanonicalTypeInternal(),
+ DeclaratorInfo.getLocEnd(),
+ ConstructorArgs);
+ })) {
SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
return ExprError();
}
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseInit.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseInit.cpp
index 7fe9862..42287d6 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseInit.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseInit.cpp
@@ -148,7 +148,7 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
Diag(NameLoc, diag::ext_gnu_old_style_field_designator)
<< FixItHint::CreateReplacement(SourceRange(NameLoc, ColonLoc),
- NewSyntax.str());
+ NewSyntax);
Designation D;
D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseObjc.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseObjc.cpp
index a597a16..691f53f 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseObjc.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseObjc.cpp
@@ -240,7 +240,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
SmallVector<Decl *, 8> ProtocolRefs;
SmallVector<SourceLocation, 8> ProtocolLocs;
if (Tok.is(tok::less) &&
- ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
+ ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, true,
LAngleLoc, EndProtoLoc))
return nullptr;
@@ -286,7 +286,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
SmallVector<SourceLocation, 8> ProtocolLocs;
SourceLocation LAngleLoc, EndProtoLoc;
if (Tok.is(tok::less) &&
- ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
+ ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, true,
LAngleLoc, EndProtoLoc))
return nullptr;
@@ -1151,7 +1151,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
bool Parser::
ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
SmallVectorImpl<SourceLocation> &ProtocolLocs,
- bool WarnOnDeclarations,
+ bool WarnOnDeclarations, bool ForObjCContainer,
SourceLocation &LAngleLoc, SourceLocation &EndLoc) {
assert(Tok.is(tok::less) && "expected <");
@@ -1186,7 +1186,7 @@ ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
return true;
// Convert the list of protocols identifiers into a list of protocol decls.
- Actions.FindProtocolDeclaration(WarnOnDeclarations,
+ Actions.FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer,
&ProtocolIdents[0], ProtocolIdents.size(),
Protocols);
return false;
@@ -1201,6 +1201,7 @@ bool Parser::ParseObjCProtocolQualifiers(DeclSpec &DS) {
SmallVector<Decl *, 8> ProtocolDecl;
SmallVector<SourceLocation, 8> ProtocolLocs;
bool Result = ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
+ false,
LAngleLoc, EndProtoLoc);
DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
ProtocolLocs.data(), LAngleLoc);
@@ -1416,7 +1417,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
SmallVector<Decl *, 8> ProtocolRefs;
SmallVector<SourceLocation, 8> ProtocolLocs;
if (Tok.is(tok::less) &&
- ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false,
+ ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false, true,
LAngleLoc, EndProtoLoc))
return DeclGroupPtrTy();
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseOpenMP.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseOpenMP.cpp
index 764619a..187289ee 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseOpenMP.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseOpenMP.cpp
@@ -223,6 +223,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
ParseScope OMPDirectiveScope(this, ScopeFlags);
Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
+ Actions.StartOpenMPClauses();
while (Tok.isNot(tok::annot_pragma_openmp_end)) {
OpenMPClauseKind CKind =
Tok.isAnnotation()
@@ -242,6 +243,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
if (Tok.is(tok::comma))
ConsumeToken();
}
+ Actions.EndOpenMPClauses();
// End location of the directive.
EndLoc = Tok.getLocation();
// Consume final annot_pragma_openmp_end.
@@ -257,13 +259,8 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
// Parse statement
AssociatedStmt = ParseStatement();
Actions.ActOnFinishOfCompoundStmt();
- if (!AssociatedStmt.isUsable()) {
- Actions.ActOnCapturedRegionError();
- CreateDirective = false;
- } else {
- AssociatedStmt = Actions.ActOnCapturedRegionEnd(AssociatedStmt.get());
- CreateDirective = AssociatedStmt.isUsable();
- }
+ AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
+ CreateDirective = AssociatedStmt.isUsable();
}
if (CreateDirective)
Directive = Actions.ActOnOpenMPExecutableDirective(
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp b/contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp
index 473be54..84256df 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp
@@ -198,9 +198,12 @@ void Parser::initializePragmaHandlers() {
OpenMPHandler.reset(new PragmaNoOpenMPHandler());
PP.AddPragmaHandler(OpenMPHandler.get());
- if (getLangOpts().MicrosoftExt) {
+ if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
MSCommentHandler.reset(new PragmaCommentHandler(Actions));
PP.AddPragmaHandler(MSCommentHandler.get());
+ }
+
+ if (getLangOpts().MicrosoftExt) {
MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions));
PP.AddPragmaHandler(MSDetectMismatchHandler.get());
MSPointersToMembers.reset(new PragmaMSPointersToMembers());
@@ -261,9 +264,12 @@ void Parser::resetPragmaHandlers() {
PP.RemovePragmaHandler(OpenMPHandler.get());
OpenMPHandler.reset();
- if (getLangOpts().MicrosoftExt) {
+ if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
PP.RemovePragmaHandler(MSCommentHandler.get());
MSCommentHandler.reset();
+ }
+
+ if (getLangOpts().MicrosoftExt) {
PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
MSDetectMismatchHandler.reset();
PP.RemovePragmaHandler(MSPointersToMembers.get());
@@ -793,8 +799,10 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
"PragmaLoopHintInfo::Toks must contain at least one token.");
// If no option is specified the argument is assumed to be a constant expr.
+ bool OptionUnroll = false;
bool StateOption = false;
- if (OptionInfo) { // Pragma unroll does not specify an option.
+ if (OptionInfo) { // Pragma Unroll does not specify an option.
+ OptionUnroll = OptionInfo->isStr("unroll");
StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
.Case("vectorize", true)
.Case("interleave", true)
@@ -806,14 +814,13 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
if (Toks[0].is(tok::eof)) {
ConsumeToken(); // The annotation token.
Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
- << /*StateArgument=*/StateOption << /*FullKeyword=*/PragmaUnroll;
+ << /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll;
return false;
}
// Validate the argument.
if (StateOption) {
ConsumeToken(); // The annotation token.
- bool OptionUnroll = OptionInfo->isStr("unroll");
SourceLocation StateLoc = Toks[0].getLocation();
IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
if (!StateInfo || ((OptionUnroll ? !StateInfo->isStr("full")
@@ -900,6 +907,7 @@ void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
<< "visibility";
return;
}
+ SourceLocation EndLoc = Tok.getLocation();
PP.LexUnexpandedToken(Tok);
if (Tok.isNot(tok::eod)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
@@ -911,6 +919,7 @@ void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
Toks[0].startToken();
Toks[0].setKind(tok::annot_pragma_vis);
Toks[0].setLocation(VisLoc);
+ Toks[0].setAnnotationEndLoc(EndLoc);
Toks[0].setAnnotationValue(
const_cast<void*>(static_cast<const void*>(VisType)));
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
@@ -1030,6 +1039,7 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP,
Toks[0].startToken();
Toks[0].setKind(tok::annot_pragma_pack);
Toks[0].setLocation(PackLoc);
+ Toks[0].setAnnotationEndLoc(RParenLoc);
Toks[0].setAnnotationValue(static_cast<void*>(Info));
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
/*OwnsTokens=*/false);
@@ -1048,6 +1058,7 @@ void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
return;
}
+ SourceLocation EndLoc = Tok.getLocation();
const IdentifierInfo *II = Tok.getIdentifierInfo();
if (II->isStr("on")) {
Kind = Sema::PMSST_ON;
@@ -1073,6 +1084,7 @@ void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
Toks[0].startToken();
Toks[0].setKind(tok::annot_pragma_msstruct);
Toks[0].setLocation(MSStructTok.getLocation());
+ Toks[0].setAnnotationEndLoc(EndLoc);
Toks[0].setAnnotationValue(reinterpret_cast<void*>(
static_cast<uintptr_t>(Kind)));
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
@@ -1128,6 +1140,7 @@ static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
return;
}
+ SourceLocation EndLoc = Tok.getLocation();
PP.Lex(Tok);
if (Tok.isNot(tok::eod)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
@@ -1142,6 +1155,7 @@ static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
Toks[0].startToken();
Toks[0].setKind(tok::annot_pragma_align);
Toks[0].setLocation(FirstTok.getLocation());
+ Toks[0].setAnnotationEndLoc(EndLoc);
Toks[0].setAnnotationValue(reinterpret_cast<void*>(
static_cast<uintptr_t>(Kind)));
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
@@ -1285,6 +1299,7 @@ void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
pragmaUnusedTok.startToken();
pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
pragmaUnusedTok.setLocation(WeakLoc);
+ pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
Toks[1] = WeakName;
Toks[2] = AliasName;
PP.EnterTokenStream(Toks, 3,
@@ -1297,6 +1312,7 @@ void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
pragmaUnusedTok.startToken();
pragmaUnusedTok.setKind(tok::annot_pragma_weak);
pragmaUnusedTok.setLocation(WeakLoc);
+ pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
Toks[1] = WeakName;
PP.EnterTokenStream(Toks, 2,
/*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
@@ -1342,6 +1358,7 @@ void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
pragmaRedefTok.startToken();
pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
pragmaRedefTok.setLocation(RedefLoc);
+ pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
Toks[1] = RedefName;
Toks[2] = AliasName;
PP.EnterTokenStream(Toks, 3,
@@ -1364,6 +1381,7 @@ PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
Toks[0].startToken();
Toks[0].setKind(tok::annot_pragma_fp_contract);
Toks[0].setLocation(Tok.getLocation());
+ Toks[0].setAnnotationEndLoc(Tok.getLocation());
Toks[0].setAnnotationValue(reinterpret_cast<void*>(
static_cast<uintptr_t>(OOS)));
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
@@ -1423,6 +1441,7 @@ PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
Toks[0].setKind(tok::annot_pragma_opencl_extension);
Toks[0].setLocation(NameLoc);
Toks[0].setAnnotationValue(data.getOpaqueValue());
+ Toks[0].setAnnotationEndLoc(StateLoc);
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
/*OwnsTokens=*/false);
@@ -1471,7 +1490,7 @@ PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
Token *Toks = new Token[Pragma.size()];
std::copy(Pragma.begin(), Pragma.end(), Toks);
PP.EnterTokenStream(Toks, Pragma.size(),
- /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true);
+ /*DisableMacroExpansion=*/false, /*OwnsTokens=*/true);
}
/// \brief Handle '#pragma pointers_to_members'
@@ -1554,6 +1573,7 @@ void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
return;
}
+ SourceLocation EndLoc = Tok.getLocation();
PP.Lex(Tok);
if (Tok.isNot(tok::eod)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
@@ -1565,6 +1585,7 @@ void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
AnnotTok.startToken();
AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
AnnotTok.setLocation(PointersToMembersLoc);
+ AnnotTok.setAnnotationEndLoc(EndLoc);
AnnotTok.setAnnotationValue(
reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
PP.EnterToken(AnnotTok);
@@ -1644,6 +1665,7 @@ void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
return;
}
+ SourceLocation EndLoc = Tok.getLocation();
PP.Lex(Tok);
if (Tok.isNot(tok::eod)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
@@ -1656,6 +1678,7 @@ void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
AnnotTok.startToken();
AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
AnnotTok.setLocation(VtorDispLoc);
+ AnnotTok.setAnnotationEndLoc(EndLoc);
AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
static_cast<uintptr_t>((Kind << 16) | (Value & 0xFFFF))));
PP.EnterToken(AnnotTok);
@@ -1672,10 +1695,13 @@ void PragmaMSPragma::HandlePragma(Preprocessor &PP,
AnnotTok.startToken();
AnnotTok.setKind(tok::annot_pragma_ms_pragma);
AnnotTok.setLocation(Tok.getLocation());
+ AnnotTok.setAnnotationEndLoc(Tok.getLocation());
SmallVector<Token, 8> TokenVector;
// Suck up all of the tokens before the eod.
- for (; Tok.isNot(tok::eod); PP.Lex(Tok))
+ for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
TokenVector.push_back(Tok);
+ AnnotTok.setAnnotationEndLoc(Tok.getLocation());
+ }
// Add a sentinal EoF token to the end of the list.
TokenVector.push_back(EoF);
// We must allocate this array with new because EnterTokenStream is going to
@@ -1786,6 +1812,14 @@ void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
return;
}
+ // On PS4, issue a warning about any pragma comments other than
+ // #pragma comment lib.
+ if (PP.getTargetInfo().getTriple().isPS4() && Kind != Sema::PCK_Lib) {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
+ << II->getName();
+ return;
+ }
+
// Read the optional string if present.
PP.Lex(Tok);
std::string ArgumentString;
@@ -1994,6 +2028,7 @@ void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
LoopHintTok.startToken();
LoopHintTok.setKind(tok::annot_pragma_loop_hint);
LoopHintTok.setLocation(PragmaName.getLocation());
+ LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
TokenList.push_back(LoopHintTok);
}
@@ -2076,6 +2111,7 @@ void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
TokenArray[0].startToken();
TokenArray[0].setKind(tok::annot_pragma_loop_hint);
TokenArray[0].setLocation(PragmaName.getLocation());
+ TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
PP.EnterTokenStream(TokenArray, 1, /*DisableMacroExpansion=*/false,
/*OwnsTokens=*/true);
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp
index 2a5f840..055bdea 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp
@@ -408,12 +408,6 @@ StmtResult Parser::ParseExprStatement() {
return Actions.ActOnExprStmt(Expr);
}
-StmtResult Parser::ParseSEHTryBlock() {
- assert(Tok.is(tok::kw___try) && "Expected '__try'");
- SourceLocation Loc = ConsumeToken();
- return ParseSEHTryBlockCommon(Loc);
-}
-
/// ParseSEHTryBlockCommon
///
/// seh-try-block:
@@ -423,8 +417,11 @@ StmtResult Parser::ParseSEHTryBlock() {
/// seh-except-block
/// seh-finally-block
///
-StmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) {
- if(Tok.isNot(tok::l_brace))
+StmtResult Parser::ParseSEHTryBlock() {
+ assert(Tok.is(tok::kw___try) && "Expected '__try'");
+ SourceLocation TryLoc = ConsumeToken();
+
+ if (Tok.isNot(tok::l_brace))
return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
@@ -441,7 +438,7 @@ StmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) {
SourceLocation Loc = ConsumeToken();
Handler = ParseSEHFinallyBlock(Loc);
} else {
- return StmtError(Diag(Tok,diag::err_seh_expected_handler));
+ return StmtError(Diag(Tok, diag::err_seh_expected_handler));
}
if(Handler.isInvalid())
@@ -466,14 +463,21 @@ StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
if (ExpectAndConsume(tok::l_paren))
return StmtError();
- ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope);
+ ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope |
+ Scope::SEHExceptScope);
if (getLangOpts().Borland) {
Ident__exception_info->setIsPoisoned(false);
Ident___exception_info->setIsPoisoned(false);
Ident_GetExceptionInfo->setIsPoisoned(false);
}
- ExprResult FilterExpr(ParseExpression());
+
+ ExprResult FilterExpr;
+ {
+ ParseScopeFlags FilterScope(this, getCurScope()->getFlags() |
+ Scope::SEHFilterScope);
+ FilterExpr = Actions.CorrectDelayedTyposInExpr(ParseExpression());
+ }
if (getLangOpts().Borland) {
Ident__exception_info->setIsPoisoned(true);
@@ -487,6 +491,9 @@ StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
if (ExpectAndConsume(tok::r_paren))
return StmtError();
+ if (Tok.isNot(tok::l_brace))
+ return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
+
StmtResult Block(ParseCompoundStatement());
if(Block.isInvalid())
@@ -500,16 +507,24 @@ StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
/// seh-finally-block:
/// '__finally' compound-statement
///
-StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) {
+StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyLoc) {
PoisonIdentifierRAIIObject raii(Ident__abnormal_termination, false),
raii2(Ident___abnormal_termination, false),
raii3(Ident_AbnormalTermination, false);
+ if (Tok.isNot(tok::l_brace))
+ return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
+
+ ParseScope FinallyScope(this, 0);
+ Actions.ActOnStartSEHFinallyBlock();
+
StmtResult Block(ParseCompoundStatement());
- if(Block.isInvalid())
+ if(Block.isInvalid()) {
+ Actions.ActOnAbortSEHFinallyBlock();
return Block;
+ }
- return Actions.ActOnSEHFinallyBlock(FinallyBlock,Block.get());
+ return Actions.ActOnFinishSEHFinallyBlock(FinallyLoc, Block.get());
}
/// Handle __leave
@@ -1253,7 +1268,7 @@ StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
// We have incremented the mangling number for the SwitchScope and the
// InnerScope, which is one too many.
if (C99orCXX)
- getCurScope()->decrementMSLocalManglingNumber();
+ getCurScope()->decrementMSManglingNumber();
// Read the body statement.
StmtResult Body(ParseStatement(TrailingElseLoc));
@@ -1674,6 +1689,12 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
FirstPart.get(),
Collection.get(),
T.getCloseLocation());
+ } else {
+ // In OpenMP loop region loop control variable must be captured and be
+ // private. Perform analysis of first part (if any).
+ if (getLangOpts().OpenMP && FirstPart.isUsable()) {
+ Actions.ActOnOpenMPLoopInitialization(ForLoc, FirstPart.get());
+ }
}
// C99 6.8.5p5 - In C99, the body of the for statement is a scope, even if
@@ -1695,7 +1716,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
// It will only be incremented if the body contains other things that would
// normally increment the mangling number (like a compound statement).
if (C99orCXXorObjC)
- getCurScope()->decrementMSLocalManglingNumber();
+ getCurScope()->decrementMSManglingNumber();
// Read the body statement.
StmtResult Body(ParseStatement(TrailingElseLoc));
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseStmtAsm.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseStmtAsm.cpp
index 7bf4da6..8ba9f15 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseStmtAsm.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseStmtAsm.cpp
@@ -530,7 +530,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
TheTarget->createMCAsmParser(*STI, *Parser, *MII, MCOptions));
std::unique_ptr<llvm::MCInstPrinter> IP(
- TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI));
+ TheTarget->createMCInstPrinter(llvm::Triple(TT), 1, *MAI, *MII, *MRI));
// Change to the Intel dialect.
Parser->setAssemblerDialect(1);
@@ -615,6 +615,7 @@ StmtResult Parser::ParseAsmStatement(bool &msAsm) {
msAsm = true;
return ParseMicrosoftAsmStatement(AsmLoc);
}
+
DeclSpec DS(AttrFactory);
SourceLocation Loc = Tok.getLocation();
ParseTypeQualifierListOpt(DS, AR_VendorAttributesParsed);
@@ -639,6 +640,15 @@ StmtResult Parser::ParseAsmStatement(bool &msAsm) {
T.consumeOpen();
ExprResult AsmString(ParseAsmStringLiteral());
+
+ // Check if GNU-style InlineAsm is disabled.
+ // Error on anything other than empty string.
+ if (!(getLangOpts().GNUAsm || AsmString.isInvalid())) {
+ const auto *SL = cast<StringLiteral>(AsmString.get());
+ if (!SL->getString().trim().empty())
+ Diag(Loc, diag::err_gnu_inline_asm_disabled);
+ }
+
if (AsmString.isInvalid()) {
// Consume up to and including the closing paren.
T.skipToEnd();
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp
index 53de72c..f1467fe 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp
@@ -14,6 +14,7 @@
#include "clang/Parse/Parser.h"
#include "RAIIObjectsForParser.h"
#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Sema/DeclSpec.h"
@@ -1301,7 +1302,8 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
// To restore the context after late parsing.
- Sema::ContextRAII GlobalSavedContext(Actions, Actions.CurContext);
+ Sema::ContextRAII GlobalSavedContext(
+ Actions, Actions.Context.getTranslationUnitDecl());
SmallVector<ParseScope*, 4> TemplateParamScopeStack;
diff --git a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp
index 7ccd209..dea7a69 100644
--- a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp
@@ -38,6 +38,26 @@ public:
return false;
}
};
+
+/// \brief RAIIObject to destroy the contents of a SmallVector of
+/// TemplateIdAnnotation pointers and clear the vector.
+class DestroyTemplateIdAnnotationsRAIIObj {
+ SmallVectorImpl<TemplateIdAnnotation *> &Container;
+
+public:
+ DestroyTemplateIdAnnotationsRAIIObj(
+ SmallVectorImpl<TemplateIdAnnotation *> &Container)
+ : Container(Container) {}
+
+ ~DestroyTemplateIdAnnotationsRAIIObj() {
+ for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I =
+ Container.begin(),
+ E = Container.end();
+ I != E; ++I)
+ (*I)->Destroy();
+ Container.clear();
+ }
+};
} // end anonymous namespace
IdentifierInfo *Parser::getSEHExceptKeyword() {
@@ -414,6 +434,15 @@ Parser::~Parser() {
PP.clearCodeCompletionHandler();
+ if (getLangOpts().DelayedTemplateParsing &&
+ !PP.isIncrementalProcessingEnabled() && !TemplateIds.empty()) {
+ // If an ASTConsumer parsed delay-parsed templates in their
+ // HandleTranslationUnit() method, TemplateIds created there were not
+ // guarded by a DestroyTemplateIdAnnotationsRAIIObj object in
+ // ParseTopLevelDecl(). Destroy them here.
+ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
+ }
+
assert(TemplateIds.empty() && "Still alive TemplateIdAnnotations around?");
}
@@ -490,26 +519,6 @@ void Parser::Initialize() {
ConsumeToken();
}
-namespace {
- /// \brief RAIIObject to destroy the contents of a SmallVector of
- /// TemplateIdAnnotation pointers and clear the vector.
- class DestroyTemplateIdAnnotationsRAIIObj {
- SmallVectorImpl<TemplateIdAnnotation *> &Container;
- public:
- DestroyTemplateIdAnnotationsRAIIObj(SmallVectorImpl<TemplateIdAnnotation *>
- &Container)
- : Container(Container) {}
-
- ~DestroyTemplateIdAnnotationsRAIIObj() {
- for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I =
- Container.begin(), E = Container.end();
- I != E; ++I)
- (*I)->Destroy();
- Container.clear();
- }
- };
-}
-
void Parser::LateTemplateParserCleanupCallback(void *P) {
// While this RAII helper doesn't bracket any actual work, the destructor will
// clean up annotations that were created during ActOnEndOfTranslationUnit
@@ -541,8 +550,14 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
return false;
case tok::annot_module_begin:
+ Actions.ActOnModuleBegin(Tok.getLocation(), reinterpret_cast<Module *>(
+ Tok.getAnnotationValue()));
+ ConsumeToken();
+ return false;
+
case tok::annot_module_end:
- // FIXME: Update visibility based on the submodule we're in.
+ Actions.ActOnModuleEnd(Tok.getLocation(), reinterpret_cast<Module *>(
+ Tok.getAnnotationValue()));
ConsumeToken();
return false;
@@ -669,8 +684,18 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
SourceLocation StartLoc = Tok.getLocation();
SourceLocation EndLoc;
+
ExprResult Result(ParseSimpleAsm(&EndLoc));
+ // Check if GNU-style InlineAsm is disabled.
+ // Empty asm string is allowed because it will not introduce
+ // any assembly code.
+ if (!(getLangOpts().GNUAsm || Result.isInvalid())) {
+ const auto *SL = cast<StringLiteral>(Result.get());
+ if (!SL->getString().trim().empty())
+ Diag(StartLoc, diag::err_gnu_inline_asm_disabled);
+ }
+
ExpectAndConsume(tok::semi, diag::err_expected_after,
"top-level asm block");
@@ -1048,7 +1073,6 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
if (TryConsumeToken(tok::equal)) {
assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
- Actions.ActOnFinishFunctionBody(Res, nullptr, false);
bool Delete = false;
SourceLocation KWLoc;
@@ -1076,6 +1100,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
SkipUntil(tok::semi);
}
+ Stmt *GeneratedBody = Res ? Res->getBody() : nullptr;
+ Actions.ActOnFinishFunctionBody(Res, GeneratedBody, false);
return Res;
}
diff --git a/contrib/llvm/tools/clang/lib/Parse/RAIIObjectsForParser.h b/contrib/llvm/tools/clang/lib/Parse/RAIIObjectsForParser.h
index a0c9c1f..36d87eb 100644
--- a/contrib/llvm/tools/clang/lib/Parse/RAIIObjectsForParser.h
+++ b/contrib/llvm/tools/clang/lib/Parse/RAIIObjectsForParser.h
@@ -58,6 +58,12 @@ namespace clang {
Active = false;
}
}
+ SuppressAccessChecks(SuppressAccessChecks &&Other)
+ : S(Other.S), DiagnosticPool(std::move(Other.DiagnosticPool)),
+ State(Other.State), Active(Other.Active) {
+ Other.Active = false;
+ }
+ void operator=(SuppressAccessChecks &&Other) = delete;
void done() {
assert(Active && "trying to end an inactive suppression");
@@ -87,8 +93,8 @@ namespace clang {
Sema::ParsingDeclState State;
bool Popped;
- ParsingDeclRAIIObject(const ParsingDeclRAIIObject &) LLVM_DELETED_FUNCTION;
- void operator=(const ParsingDeclRAIIObject &) LLVM_DELETED_FUNCTION;
+ ParsingDeclRAIIObject(const ParsingDeclRAIIObject &) = delete;
+ void operator=(const ParsingDeclRAIIObject &) = delete;
public:
enum NoParent_t { NoParent };
@@ -244,8 +250,8 @@ namespace clang {
/// the way they used to be. This is used to handle __extension__ in the
/// parser.
class ExtensionRAIIObject {
- ExtensionRAIIObject(const ExtensionRAIIObject &) LLVM_DELETED_FUNCTION;
- void operator=(const ExtensionRAIIObject &) LLVM_DELETED_FUNCTION;
+ ExtensionRAIIObject(const ExtensionRAIIObject &) = delete;
+ void operator=(const ExtensionRAIIObject &) = delete;
DiagnosticsEngine &Diags;
public:
@@ -423,7 +429,13 @@ namespace clang {
if (P.Tok.is(Close)) {
LClose = (P.*Consumer)();
return false;
- }
+ } else if (P.Tok.is(tok::semi) && P.NextToken().is(Close)) {
+ SourceLocation SemiLoc = P.ConsumeToken();
+ P.Diag(SemiLoc, diag::err_unexpected_semi)
+ << Close << FixItHint::CreateRemoval(SourceRange(SemiLoc, SemiLoc));
+ LClose = (P.*Consumer)();
+ return false;
+ }
return diagnoseMissingClose();
}
OpenPOWER on IntegriCloud