aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Parse
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
commit486754660bb926339aefcf012a3f848592babb8b (patch)
treeecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Parse
parent55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff)
downloadsrc-486754660bb926339aefcf012a3f848592babb8b.tar.gz
src-486754660bb926339aefcf012a3f848592babb8b.zip
Vendor import of clang trunk r338150:vendor/clang/clang-trunk-r338150
Notes
Notes: svn path=/vendor/clang/dist/; revision=336815 svn path=/vendor/clang/clang-trunk-r338150/; revision=336816; tag=vendor/clang/clang-trunk-r338150
Diffstat (limited to 'lib/Parse')
-rw-r--r--lib/Parse/ParseAST.cpp18
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp24
-rw-r--r--lib/Parse/ParseDecl.cpp738
-rw-r--r--lib/Parse/ParseDeclCXX.cpp283
-rw-r--r--lib/Parse/ParseExpr.cpp208
-rw-r--r--lib/Parse/ParseExprCXX.cpp348
-rw-r--r--lib/Parse/ParseObjc.cpp197
-rw-r--r--lib/Parse/ParseOpenMP.cpp319
-rw-r--r--lib/Parse/ParsePragma.cpp208
-rw-r--r--lib/Parse/ParseStmt.cpp74
-rw-r--r--lib/Parse/ParseStmtAsm.cpp2
-rw-r--r--lib/Parse/ParseTemplate.cpp383
-rw-r--r--lib/Parse/ParseTentative.cpp63
-rw-r--r--lib/Parse/Parser.cpp81
14 files changed, 1723 insertions, 1223 deletions
diff --git a/lib/Parse/ParseAST.cpp b/lib/Parse/ParseAST.cpp
index d018d4c08ed9..696506099e58 100644
--- a/lib/Parse/ParseAST.cpp
+++ b/lib/Parse/ParseAST.cpp
@@ -21,6 +21,7 @@
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaConsumer.h"
+#include "clang/Sema/TemplateInstCallback.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include <cstdio>
#include <memory>
@@ -121,6 +122,10 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
bool OldCollectStats = PrintStats;
std::swap(OldCollectStats, S.CollectStats);
+ // Initialize the template instantiation observer chain.
+ // FIXME: See note on "finalize" below.
+ initialize(S.TemplateInstCallbacks, S);
+
ASTConsumer *Consumer = &S.getASTConsumer();
std::unique_ptr<Parser> ParseOP(
@@ -136,6 +141,12 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
CleanupParser(ParseOP.get());
S.getPreprocessor().EnterMainSourceFile();
+ if (!S.getPreprocessor().getCurrentLexer()) {
+ // If a PCH through header is specified that does not have an include in
+ // the source, there won't be any tokens or a Lexer.
+ return;
+ }
+
P.Initialize();
Parser::DeclGroupPtrTy ADecl;
@@ -158,6 +169,13 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
Consumer->HandleTranslationUnit(S.getASTContext());
+ // Finalize the template instantiation observer chain.
+ // FIXME: This (and init.) should be done in the Sema class, but because
+ // Sema does not have a reliable "Finalize" function (it has a
+ // destructor, but it is not guaranteed to be called ("-disable-free")).
+ // So, do the initialization above and do the finalization here:
+ finalize(S.TemplateInstCallbacks, S);
+
std::swap(OldCollectStats, S.CollectStats);
if (PrintStats) {
llvm::errs() << "\nSTATISTICS:\n";
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 2b3d4ba85bd8..27d48be0e3eb 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -22,12 +22,10 @@ using namespace clang;
/// ParseCXXInlineMethodDef - We parsed and verified that the specified
/// Declarator is a well formed C++ inline method definition. Now lex its body
/// and store its tokens for parsing after the C++ class is complete.
-NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
- AttributeList *AccessAttrs,
- ParsingDeclarator &D,
- const ParsedTemplateInfo &TemplateInfo,
- const VirtSpecifiers& VS,
- SourceLocation PureSpecLoc) {
+NamedDecl *Parser::ParseCXXInlineMethodDef(
+ AccessSpecifier AS, ParsedAttributes &AccessAttrs, ParsingDeclarator &D,
+ const ParsedTemplateInfo &TemplateInfo, const VirtSpecifiers &VS,
+ SourceLocation PureSpecLoc) {
assert(D.isFunctionDeclarator() && "This isn't a function declarator!");
assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try, tok::equal) &&
"Current token not a '{', ':', '=', or 'try'!");
@@ -312,6 +310,8 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
Actions.ActOnDelayedCXXMethodParameter(getCurScope(), Param);
std::unique_ptr<CachedTokens> Toks = std::move(LM.DefaultArgs[I].Toks);
if (Toks) {
+ ParenBraceBracketBalancer BalancerRAIIObj(*this);
+
// Mark the end of the default argument so that we know when to stop when
// we parse it later on.
Token LastDefaultArgToken = Toks->back();
@@ -384,6 +384,8 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
// Parse a delayed exception-specification, if there is one.
if (CachedTokens *Toks = LM.ExceptionSpecTokens) {
+ ParenBraceBracketBalancer BalancerRAIIObj(*this);
+
// Add the 'stop' token.
Token LastExceptionSpecToken = Toks->back();
Token ExceptionSpecEnd;
@@ -489,6 +491,8 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
++CurTemplateDepthTracker;
}
+ ParenBraceBracketBalancer BalancerRAIIObj(*this);
+
assert(!LM.Toks.empty() && "Empty body!");
Token LastBodyToken = LM.Toks.back();
Token BodyEnd;
@@ -609,6 +613,8 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
if (!MI.Field || MI.Field->isInvalidDecl())
return;
+ ParenBraceBracketBalancer BalancerRAIIObj(*this);
+
// Append the current token at the end of the new token stream so that it
// doesn't get lost.
MI.Toks.push_back(Tok);
@@ -733,7 +739,7 @@ bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
}
}
-/// \brief Consume tokens and store them in the passed token container until
+/// Consume tokens and store them in the passed token container until
/// we've passed the try keyword and constructor initializers and have consumed
/// the opening brace of the function body. The opening brace will be consumed
/// if and only if there was no error.
@@ -937,7 +943,7 @@ bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
}
}
-/// \brief Consume and store tokens from the '?' to the ':' in a conditional
+/// Consume and store tokens from the '?' to the ':' in a conditional
/// expression.
bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) {
// Consume '?'.
@@ -962,7 +968,7 @@ bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) {
return true;
}
-/// \brief A tentative parsing action that can also revert token annotations.
+/// A tentative parsing action that can also revert token annotations.
class Parser::UnannotatedTentativeParsingAction : public TentativeParsingAction {
public:
explicit UnannotatedTentativeParsingAction(Parser &Self,
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 2a999399fb50..4f6bb08bdc64 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -15,6 +15,7 @@
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/Attributes.h"
#include "clang/Basic/CharInfo.h"
@@ -22,14 +23,12 @@
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/ParsedTemplate.h"
-#include "clang/Sema/PrettyDeclStackTrace.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/ScopedPrinter.h"
using namespace clang;
@@ -43,18 +42,18 @@ using namespace clang;
///
/// Called type-id in C++.
TypeResult Parser::ParseTypeName(SourceRange *Range,
- Declarator::TheContext Context,
+ DeclaratorContext Context,
AccessSpecifier AS,
Decl **OwnedType,
ParsedAttributes *Attrs) {
DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
- if (DSC == DSC_normal)
- DSC = DSC_type_specifier;
+ if (DSC == DeclSpecContext::DSC_normal)
+ DSC = DeclSpecContext::DSC_type_specifier;
// Parse the common declaration-specifiers piece.
DeclSpec DS(AttrFactory);
if (Attrs)
- DS.addAttributes(Attrs->getList());
+ DS.addAttributes(*Attrs);
ParseSpecifierQualifierList(DS, AS, DSC);
if (OwnedType)
*OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : nullptr;
@@ -71,7 +70,7 @@ TypeResult Parser::ParseTypeName(SourceRange *Range,
return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
}
-/// \brief Normalizes an attribute name by dropping prefixed and suffixed __.
+/// Normalizes an attribute name by dropping prefixed and suffixed __.
static StringRef normalizeAttrName(StringRef Name) {
if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
return Name.drop_front(2).drop_back(2);
@@ -163,14 +162,14 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
if (Tok.isNot(tok::l_paren)) {
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- AttributeList::AS_GNU);
+ ParsedAttr::AS_GNU);
continue;
}
// Handle "parameterized" attributes
if (!LateAttrs || !isAttributeLateParsed(*AttrName)) {
ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc, nullptr,
- SourceLocation(), AttributeList::AS_GNU, D);
+ SourceLocation(), ParsedAttr::AS_GNU, D);
continue;
}
@@ -207,7 +206,7 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
}
}
-/// \brief Determine whether the given attribute has an identifier argument.
+/// Determine whether the given attribute has an identifier argument.
static bool attributeHasIdentifierArg(const IdentifierInfo &II) {
#define CLANG_ATTR_IDENTIFIER_ARG_LIST
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
@@ -216,7 +215,16 @@ static bool attributeHasIdentifierArg(const IdentifierInfo &II) {
#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
}
-/// \brief Determine whether the given attribute parses a type argument.
+/// Determine whether the given attribute has a variadic identifier argument.
+static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II) {
+#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
+ return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
+#include "clang/Parse/AttrParserStringSwitches.inc"
+ .Default(false);
+#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
+}
+
+/// Determine whether the given attribute parses a type argument.
static bool attributeIsTypeArgAttr(const IdentifierInfo &II) {
#define CLANG_ATTR_TYPE_ARG_LIST
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
@@ -225,7 +233,7 @@ static bool attributeIsTypeArgAttr(const IdentifierInfo &II) {
#undef CLANG_ATTR_TYPE_ARG_LIST
}
-/// \brief Determine whether the given attribute requires parsing its arguments
+/// Determine whether the given attribute requires parsing its arguments
/// in an unevaluated context or not.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II) {
#define CLANG_ATTR_ARG_CONTEXT_LIST
@@ -250,7 +258,7 @@ void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
SourceLocation *EndLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax) {
+ ParsedAttr::Syntax Syntax) {
BalancedDelimiterTracker Parens(*this, tok::l_paren);
Parens.consumeOpen();
@@ -276,21 +284,22 @@ void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
unsigned Parser::ParseAttributeArgsCommon(
IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc, AttributeList::Syntax Syntax) {
+ SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax) {
// Ignore the left paren location for now.
ConsumeParen();
ArgsVector ArgExprs;
if (Tok.is(tok::identifier)) {
// If this attribute wants an 'identifier' argument, make it so.
- bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName);
- AttributeList::Kind AttrKind =
- AttributeList::getKind(AttrName, ScopeName, Syntax);
+ bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName) ||
+ attributeHasVariadicIdentifierArg(*AttrName);
+ ParsedAttr::Kind AttrKind =
+ ParsedAttr::getKind(AttrName, ScopeName, Syntax);
// If we don't know how to parse this attribute, but this is the only
// token in this argument, assume it's meant to be an identifier.
- if (AttrKind == AttributeList::UnknownAttribute ||
- AttrKind == AttributeList::IgnoredAttribute) {
+ if (AttrKind == ParsedAttr::UnknownAttribute ||
+ AttrKind == ParsedAttr::IgnoredAttribute) {
const Token &Next = NextToken();
IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma);
}
@@ -306,21 +315,25 @@ unsigned Parser::ParseAttributeArgsCommon(
// Parse the non-empty comma-separated list of expressions.
do {
- bool Uneval = attributeParsedArgsUnevaluated(*AttrName);
- EnterExpressionEvaluationContext Unevaluated(
- Actions,
- Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
- : Sema::ExpressionEvaluationContext::ConstantEvaluated,
- /*LambdaContextDecl=*/nullptr,
- /*IsDecltype=*/false);
-
- ExprResult ArgExpr(
- Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
- if (ArgExpr.isInvalid()) {
- SkipUntil(tok::r_paren, StopAtSemi);
- return 0;
+ ExprResult ArgExpr;
+ if (Tok.is(tok::identifier) &&
+ attributeHasVariadicIdentifierArg(*AttrName)) {
+ ArgExprs.push_back(ParseIdentifierLoc());
+ } else {
+ bool Uneval = attributeParsedArgsUnevaluated(*AttrName);
+ EnterExpressionEvaluationContext Unevaluated(
+ Actions,
+ Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
+ : Sema::ExpressionEvaluationContext::ConstantEvaluated);
+
+ ExprResult ArgExpr(
+ Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
+ if (ArgExpr.isInvalid()) {
+ SkipUntil(tok::r_paren, StopAtSemi);
+ return 0;
+ }
+ ArgExprs.push_back(ArgExpr.get());
}
- ArgExprs.push_back(ArgExpr.get());
// Eat the comma, move to the next argument
} while (TryConsumeToken(tok::comma));
}
@@ -346,27 +359,27 @@ void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
SourceLocation *EndLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax,
+ ParsedAttr::Syntax Syntax,
Declarator *D) {
assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
- AttributeList::Kind AttrKind =
- AttributeList::getKind(AttrName, ScopeName, Syntax);
+ ParsedAttr::Kind AttrKind =
+ ParsedAttr::getKind(AttrName, ScopeName, Syntax);
- if (AttrKind == AttributeList::AT_Availability) {
+ if (AttrKind == ParsedAttr::AT_Availability) {
ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
ScopeLoc, Syntax);
return;
- } else if (AttrKind == AttributeList::AT_ExternalSourceSymbol) {
+ } else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
return;
- } else if (AttrKind == AttributeList::AT_ObjCBridgeRelated) {
+ } else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
return;
- } else if (AttrKind == AttributeList::AT_TypeTagForDatatype) {
+ } else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
return;
@@ -398,20 +411,34 @@ void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
unsigned Parser::ParseClangAttributeArgs(
IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc, AttributeList::Syntax Syntax) {
+ SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax) {
assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
- AttributeList::Kind AttrKind =
- AttributeList::getKind(AttrName, ScopeName, Syntax);
+ ParsedAttr::Kind AttrKind =
+ ParsedAttr::getKind(AttrName, ScopeName, Syntax);
- if (AttrKind == AttributeList::AT_ExternalSourceSymbol) {
+ switch (AttrKind) {
+ default:
+ return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
+ ScopeName, ScopeLoc, Syntax);
+ case ParsedAttr::AT_ExternalSourceSymbol:
ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
- return Attrs.getList() ? Attrs.getList()->getNumArgs() : 0;
+ break;
+ case ParsedAttr::AT_Availability:
+ ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
+ ScopeLoc, Syntax);
+ break;
+ case ParsedAttr::AT_ObjCBridgeRelated:
+ ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+ ScopeName, ScopeLoc, Syntax);
+ break;
+ case ParsedAttr::AT_TypeTagForDatatype:
+ ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+ ScopeName, ScopeLoc, Syntax);
+ break;
}
-
- return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
- ScopeName, ScopeLoc, Syntax);
+ return !Attrs.empty() ? Attrs.begin()->getNumArgs() : 0;
}
bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
@@ -538,19 +565,18 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
if (!HasInvalidAccessor)
Attrs.addNewPropertyAttr(AttrName, AttrNameLoc, nullptr, SourceLocation(),
AccessorNames[AK_Get], AccessorNames[AK_Put],
- AttributeList::AS_Declspec);
+ ParsedAttr::AS_Declspec);
T.skipToEnd();
return !HasInvalidAccessor;
}
unsigned NumArgs =
ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr,
- SourceLocation(), AttributeList::AS_Declspec);
+ SourceLocation(), ParsedAttr::AS_Declspec);
// If this attribute's args were parsed, and it was expected to have
// arguments but none were provided, emit a diagnostic.
- const AttributeList *Attr = Attrs.getList();
- if (Attr && Attr->getMaxArgs() && !NumArgs) {
+ if (!Attrs.empty() && Attrs.begin()->getMaxArgs() && !NumArgs) {
Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
return false;
}
@@ -621,7 +647,7 @@ void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
if (!AttrHandled)
Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- AttributeList::AS_Declspec);
+ ParsedAttr::AS_Declspec);
}
T.consumeClose();
if (End)
@@ -647,7 +673,7 @@ void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- AttributeList::AS_Keyword);
+ ParsedAttr::AS_Keyword);
break;
}
default:
@@ -698,7 +724,7 @@ void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- AttributeList::AS_Keyword);
+ ParsedAttr::AS_Keyword);
}
}
@@ -708,7 +734,7 @@ void Parser::ParseOpenCLKernelAttributes(ParsedAttributes &attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- AttributeList::AS_Keyword);
+ ParsedAttr::AS_Keyword);
}
}
@@ -716,7 +742,7 @@ void Parser::ParseOpenCLQualifiers(ParsedAttributes &Attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = Tok.getLocation();
Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- AttributeList::AS_Keyword);
+ ParsedAttr::AS_Keyword);
}
void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) {
@@ -732,7 +758,7 @@ void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) {
Diag(AttrNameLoc, diag::ext_nullability)
<< AttrName;
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- AttributeList::AS_Keyword);
+ ParsedAttr::AS_Keyword);
break;
}
default:
@@ -745,12 +771,14 @@ static bool VersionNumberSeparator(const char Separator) {
return (Separator == '.' || Separator == '_');
}
-/// \brief Parse a version number.
+/// Parse a version number.
///
/// version:
/// simple-integer
-/// simple-integer ',' simple-integer
-/// simple-integer ',' simple-integer ',' simple-integer
+/// simple-integer '.' simple-integer
+/// simple-integer '_' simple-integer
+/// simple-integer '.' simple-integer '.' simple-integer
+/// simple-integer '_' simple-integer '_' simple-integer
VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
@@ -828,7 +856,7 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
return VersionTuple();
}
- return VersionTuple(Major, Minor, (AfterMajorSeparator == '_'));
+ return VersionTuple(Major, Minor);
}
const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
@@ -859,10 +887,10 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
return VersionTuple();
}
ConsumeToken();
- return VersionTuple(Major, Minor, Subminor, (AfterMajorSeparator == '_'));
+ return VersionTuple(Major, Minor, Subminor);
}
-/// \brief Parse the contents of the "availability" attribute.
+/// Parse the contents of the "availability" attribute.
///
/// availability-attribute:
/// 'availability' '(' platform ',' opt-strict version-arg-list,
@@ -893,7 +921,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
SourceLocation *endLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax) {
+ ParsedAttr::Syntax Syntax) {
enum { Introduced, Deprecated, Obsoleted, Unknown };
AvailabilityChange Changes[Unknown];
ExprResult MessageExpr, ReplacementExpr;
@@ -1094,7 +1122,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
Syntax, StrictLoc, ReplacementExpr.get());
}
-/// \brief Parse the contents of the "external_source_symbol" attribute.
+/// Parse the contents of the "external_source_symbol" attribute.
///
/// external-source-symbol-attribute:
/// 'external_source_symbol' '(' keyword-arg-list ')'
@@ -1110,7 +1138,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
void Parser::ParseExternalSourceSymbolAttribute(
IdentifierInfo &ExternalSourceSymbol, SourceLocation Loc,
ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc, AttributeList::Syntax Syntax) {
+ SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax) {
// Opening '('.
BalancedDelimiterTracker T(*this, tok::l_paren);
if (T.expectAndConsume())
@@ -1207,7 +1235,7 @@ void Parser::ParseExternalSourceSymbolAttribute(
ScopeName, ScopeLoc, Args, llvm::array_lengthof(Args), Syntax);
}
-/// \brief Parse the contents of the "objc_bridge_related" attribute.
+/// Parse the contents of the "objc_bridge_related" attribute.
/// objc_bridge_related '(' related_class ',' opt-class_method ',' opt-instance_method ')'
/// related_class:
/// Identifier
@@ -1224,7 +1252,7 @@ void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
SourceLocation *endLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax) {
+ ParsedAttr::Syntax Syntax) {
// Opening '('.
BalancedDelimiterTracker T(*this, tok::l_paren);
if (T.consumeOpen()) {
@@ -1244,7 +1272,9 @@ void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
return;
}
- // Parse optional class method name.
+ // Parse class method name. It's non-optional in the sense that a trailing
+ // comma is required, but it can be the empty string, and then we record a
+ // nullptr.
IdentifierLoc *ClassMethod = nullptr;
if (Tok.is(tok::identifier)) {
ClassMethod = ParseIdentifierLoc();
@@ -1263,7 +1293,8 @@ void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
return;
}
- // Parse optional instance method name.
+ // Parse instance method name. Also non-optional but empty string is
+ // permitted.
IdentifierLoc *InstanceMethod = nullptr;
if (Tok.is(tok::identifier))
InstanceMethod = ParseIdentifierLoc();
@@ -1335,7 +1366,7 @@ void Parser::ParseLexedAttributes(ParsingClass &Class) {
Class.TagOrTemplate);
}
-/// \brief Parse all attributes in LAs, and attach them to Decl D.
+/// Parse all attributes in LAs, and attach them to Decl D.
void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
bool EnterScope, bool OnDefinition) {
assert(LAs.parseSoon() &&
@@ -1349,7 +1380,7 @@ void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
LAs.clear();
}
-/// \brief Finish parsing an attribute for which parsing was delayed.
+/// Finish parsing an attribute for which parsing was delayed.
/// This will be called at the end of parsing a class declaration
/// for each LateParsedAttribute. We consume the saved tokens and
/// create an attribute with the arguments filled in. We add this
@@ -1400,7 +1431,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
- nullptr, SourceLocation(), AttributeList::AS_GNU,
+ nullptr, SourceLocation(), ParsedAttr::AS_GNU,
nullptr);
if (HasFunScope) {
@@ -1414,16 +1445,15 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
// If there are multiple decls, then the decl cannot be within the
// function scope.
ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
- nullptr, SourceLocation(), AttributeList::AS_GNU,
+ nullptr, SourceLocation(), ParsedAttr::AS_GNU,
nullptr);
}
} else {
Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
}
- const AttributeList *AL = Attrs.getList();
- if (OnDefinition && AL && !AL->isCXX11Attribute() &&
- AL->isKnownToGCC())
+ if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&
+ Attrs.begin()->isKnownToGCC())
Diag(Tok, diag::warn_attribute_on_function_definition)
<< &LA.AttrName;
@@ -1445,7 +1475,7 @@ void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
SourceLocation *EndLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax) {
+ ParsedAttr::Syntax Syntax) {
assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
BalancedDelimiterTracker T(*this, tok::l_paren);
@@ -1535,7 +1565,7 @@ bool Parser::DiagnoseProhibitedCXX11Attribute() {
llvm_unreachable("All cases handled above.");
}
-/// \brief We have found the opening square brackets of a C++11
+/// We have found the opening square brackets of a C++11
/// attribute-specifier in a location where an attribute is not permitted, but
/// we know where the attributes ought to be written. Parse them anyway, and
/// provide a fixit moving them to the right place.
@@ -1554,29 +1584,27 @@ void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
<< FixItHint::CreateRemoval(AttrRange);
}
-void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs,
- const SourceLocation CorrectLocation) {
+void Parser::DiagnoseProhibitedAttributes(
+ const SourceRange &Range, const SourceLocation CorrectLocation) {
if (CorrectLocation.isValid()) {
- CharSourceRange AttrRange(attrs.Range, true);
+ CharSourceRange AttrRange(Range, true);
Diag(CorrectLocation, diag::err_attributes_misplaced)
<< FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)
<< FixItHint::CreateRemoval(AttrRange);
} else
- Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) << attrs.Range;
+ Diag(Range.getBegin(), diag::err_attributes_not_allowed) << Range;
}
void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs,
unsigned DiagID) {
- for (AttributeList *Attr = Attrs.getList(); Attr; Attr = Attr->getNext()) {
- if (!Attr->isCXX11Attribute() && !Attr->isC2xAttribute())
+ for (const ParsedAttr &AL : Attrs) {
+ if (!AL.isCXX11Attribute() && !AL.isC2xAttribute())
continue;
- if (Attr->getKind() == AttributeList::UnknownAttribute)
- Diag(Attr->getLoc(), diag::warn_unknown_attribute_ignored)
- << Attr->getName();
+ if (AL.getKind() == ParsedAttr::UnknownAttribute)
+ Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL.getName();
else {
- Diag(Attr->getLoc(), DiagID)
- << Attr->getName();
- Attr->setInvalid();
+ Diag(AL.getLoc(), DiagID) << AL.getName();
+ AL.setInvalid();
}
}
}
@@ -1594,52 +1622,24 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
if (TUK == Sema::TUK_Reference)
return;
- ParsedAttributes &PA = DS.getAttributes();
- AttributeList *AL = PA.getList();
- AttributeList *Prev = nullptr;
- AttributeList *TypeAttrHead = nullptr;
- AttributeList *TypeAttrTail = nullptr;
- while (AL) {
- AttributeList *Next = AL->getNext();
-
- if ((AL->getKind() == AttributeList::AT_Aligned &&
- AL->isDeclspecAttribute()) ||
- AL->isMicrosoftAttribute()) {
- // Stitch the attribute into the tag's attribute list.
- if (TypeAttrTail)
- TypeAttrTail->setNext(AL);
- else
- TypeAttrHead = AL;
- TypeAttrTail = AL;
- TypeAttrTail->setNext(nullptr);
-
- // 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;
- }
+ llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
- AL = Next;
+ for (ParsedAttr &AL : DS.getAttributes()) {
+ if ((AL.getKind() == ParsedAttr::AT_Aligned &&
+ AL.isDeclspecAttribute()) ||
+ AL.isMicrosoftAttribute())
+ ToBeMoved.push_back(&AL);
}
- // Find end of type attributes Attrs and add NewTypeAttributes in the same
- // order they were in originally. (Remember, in AttributeList things earlier
- // in source order are later in the list, since new attributes are added to
- // the front of the list.)
- Attrs.addAllAtEnd(TypeAttrHead);
+ for (ParsedAttr *AL : ToBeMoved) {
+ DS.getAttributes().remove(AL);
+ Attrs.addAtEnd(AL);
+ }
}
/// 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
+/// 'Context' should be a DeclaratorContext value. This returns the
/// location of the semicolon in DeclEnd.
///
/// declaration: [C99 6.7]
@@ -1653,7 +1653,7 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
/// [C++11/C11] static_assert-declaration
/// others... [FIXME]
///
-Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
+Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs) {
ParenBraceBracketBalancer BalancerRAIIObj(*this);
@@ -1666,7 +1666,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
case tok::kw_template:
case tok::kw_export:
ProhibitAttributes(attrs);
- SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
+ SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd, attrs);
break;
case tok::kw_inline:
// Could be the start of an inline namespace. Allowed as an ext in C++03.
@@ -1714,7 +1714,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
/// of a simple-declaration. If we find that we are, we also parse the
/// for-range-initializer, and place it here.
Parser::DeclGroupPtrTy
-Parser::ParseSimpleDeclaration(unsigned Context,
+Parser::ParseSimpleDeclaration(DeclaratorContext Context,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &Attrs,
bool RequireSemi, ForRangeInit *FRI) {
@@ -1753,7 +1753,7 @@ Parser::ParseSimpleDeclaration(unsigned Context,
/// Returns true if this might be the start of a declarator, or a common typo
/// for a declarator.
-bool Parser::MightBeDeclarator(unsigned Context) {
+bool Parser::MightBeDeclarator(DeclaratorContext Context) {
switch (Tok.getKind()) {
case tok::annot_cxxscope:
case tok::annot_template_id:
@@ -1772,11 +1772,12 @@ bool Parser::MightBeDeclarator(unsigned Context) {
return getLangOpts().CPlusPlus;
case tok::l_square: // Might be an attribute on an unnamed bit-field.
- return Context == Declarator::MemberContext && getLangOpts().CPlusPlus11 &&
- NextToken().is(tok::l_square);
+ return Context == DeclaratorContext::MemberContext &&
+ getLangOpts().CPlusPlus11 && NextToken().is(tok::l_square);
case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
- return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
+ return Context == DeclaratorContext::MemberContext ||
+ getLangOpts().CPlusPlus;
case tok::identifier:
switch (NextToken().getKind()) {
@@ -1802,8 +1803,9 @@ bool Parser::MightBeDeclarator(unsigned Context) {
// At namespace scope, 'identifier:' is probably a typo for 'identifier::'
// and in block scope it's probably a label. Inside a class definition,
// this is a bit-field.
- return Context == Declarator::MemberContext ||
- (getLangOpts().CPlusPlus && Context == Declarator::FileContext);
+ return Context == DeclaratorContext::MemberContext ||
+ (getLangOpts().CPlusPlus &&
+ Context == DeclaratorContext::FileContext);
case tok::identifier: // Possible virt-specifier.
return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken());
@@ -1902,11 +1904,11 @@ void Parser::SkipMalformedDecl() {
/// definition or a group of object declarations, actually parse the
/// result.
Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
- unsigned Context,
+ DeclaratorContext Context,
SourceLocation *DeclEnd,
ForRangeInit *FRI) {
// Parse the first declarator.
- ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
+ ParsingDeclarator D(*this, DS, Context);
ParseDeclarator(D);
// Bail out if the first declarator didn't seem well-formed.
@@ -1953,7 +1955,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// Function definitions are only allowed at file scope and in C++ classes.
// The C++ inline method definition case is handled elsewhere, so we only
// need to handle the file scope definition case.
- if (Context == Declarator::FileContext) {
+ if (Context == DeclaratorContext::FileContext) {
if (isStartOfFunctionDefinition(D)) {
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
Diag(Tok, diag::err_function_declared_typedef);
@@ -2008,8 +2010,13 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
}
Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
- if (IsForRangeLoop)
+ if (IsForRangeLoop) {
Actions.ActOnCXXForRangeDecl(ThisDecl);
+ } else {
+ // Obj-C for loop
+ if (auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
+ VD->setObjCForDecl(true);
+ }
Actions.FinalizeDeclaration(ThisDecl);
D.complete(ThisDecl);
return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, ThisDecl);
@@ -2024,7 +2031,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
if (FirstDecl)
DeclsInGroup.push_back(FirstDecl);
- bool ExpectSemi = Context != Declarator::ForContext;
+ bool ExpectSemi = Context != DeclaratorContext::ForContext;
// If we don't have a comma, it is either the end of the list (a ';') or an
// error, bail out.
@@ -2070,7 +2077,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
*DeclEnd = Tok.getLocation();
if (ExpectSemi &&
- ExpectAndConsumeSemi(Context == Declarator::FileContext
+ ExpectAndConsumeSemi(Context == DeclaratorContext::FileContext
? diag::err_invalid_token_after_toplevel_declarator
: diag::err_expected_semi_declaration)) {
// Okay, there was no semicolon and one was expected. If we see a
@@ -2105,7 +2112,7 @@ bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
return false;
}
-/// \brief Parse 'declaration' after parsing 'declaration-specifiers
+/// Parse 'declaration' after parsing 'declaration-specifiers
/// declarator'. This method parses the remainder of the declaration
/// (including any attributes or initializer, among other things) and
/// finalizes the declaration.
@@ -2199,7 +2206,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
// FIXME: This check should be for a variable template instantiation only.
// Check that this is a valid instantiation
- if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
+ if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {
// If the declarator-id is not a template-id, issue a diagnostic and
// recover by ignoring the 'template' keyword.
Diag(Tok, diag::err_template_defn_explicit_instantiation)
@@ -2273,8 +2280,8 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
if (Init.isInvalid()) {
SmallVector<tok::TokenKind, 2> StopTokens;
StopTokens.push_back(tok::comma);
- if (D.getContext() == Declarator::ForContext ||
- D.getContext() == Declarator::InitStmtContext)
+ if (D.getContext() == DeclaratorContext::ForContext ||
+ D.getContext() == DeclaratorContext::InitStmtContext)
StopTokens.push_back(tok::r_paren);
SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
Actions.ActOnInitializerError(ThisDecl);
@@ -2397,7 +2404,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
}
// Issue diagnostic and remove constexpr specfier if present.
- if (DS.isConstexprSpecified() && DSC != DSC_condition) {
+ if (DS.isConstexprSpecified() && DSC != DeclSpecContext::DSC_condition) {
Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
DS.ClearConstexprSpec();
}
@@ -2444,7 +2451,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
SourceLocation Loc = Tok.getLocation();
// If we see an identifier that is not a type name, we normally would
- // parse it as the identifer being declared. However, when a typename
+ // parse it as the identifier being declared. However, when a typename
// is typo'd or the definition is not included, this will incorrectly
// parse the typename as the identifier name and fall over misparsing
// later parts of the diagnostic.
@@ -2486,7 +2493,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
// classes.
if (ParsedType T = Actions.ActOnMSVCUnknownTypeName(
*Tok.getIdentifierInfo(), Tok.getLocation(),
- DSC == DSC_template_type_arg)) {
+ DSC == DeclSpecContext::DSC_template_type_arg)) {
const char *PrevSpec;
unsigned DiagID;
DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T,
@@ -2540,18 +2547,20 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
// Parse this as a tag as if the missing tag were present.
if (TagKind == tok::kw_enum)
- ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
+ ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
+ DeclSpecContext::DSC_normal);
else
ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
- /*EnteringContext*/ false, DSC_normal, Attrs);
+ /*EnteringContext*/ false,
+ DeclSpecContext::DSC_normal, Attrs);
return true;
}
}
// Determine whether this identifier could plausibly be the name of something
// being declared (with a missing type).
- if (!isTypeSpecifier(DSC) &&
- (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
+ if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
+ DSC == DeclSpecContext::DSC_class)) {
// Look ahead to the next token to try to figure out what this declaration
// was supposed to be.
switch (NextToken().getKind()) {
@@ -2575,7 +2584,8 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
// If we're in a context where we could be declaring a constructor,
// check whether this is a constructor declaration with a bogus name.
- if (DSC == DSC_class || (DSC == DSC_top_level && SS)) {
+ if (DSC == DeclSpecContext::DSC_class ||
+ (DSC == DeclSpecContext::DSC_top_level && SS)) {
IdentifierInfo *II = Tok.getIdentifierInfo();
if (Actions.isCurrentClassNameTypo(II, SS)) {
Diag(Loc, diag::err_constructor_bad_name)
@@ -2651,27 +2661,29 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
return false;
}
-/// \brief Determine the declaration specifier context from the declarator
+/// Determine the declaration specifier context from the declarator
/// context.
///
/// \param Context the declarator context, which is one of the
-/// Declarator::TheContext enumerator values.
+/// DeclaratorContext enumerator values.
Parser::DeclSpecContext
-Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
- if (Context == Declarator::MemberContext)
- return DSC_class;
- if (Context == Declarator::FileContext)
- return DSC_top_level;
- if (Context == Declarator::TemplateParamContext)
- return DSC_template_param;
- if (Context == Declarator::TemplateTypeArgContext)
- return DSC_template_type_arg;
- if (Context == Declarator::TrailingReturnContext)
- return DSC_trailing;
- if (Context == Declarator::AliasDeclContext ||
- Context == Declarator::AliasTemplateContext)
- return DSC_alias_declaration;
- return DSC_normal;
+Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) {
+ if (Context == DeclaratorContext::MemberContext)
+ return DeclSpecContext::DSC_class;
+ if (Context == DeclaratorContext::FileContext)
+ return DeclSpecContext::DSC_top_level;
+ if (Context == DeclaratorContext::TemplateParamContext)
+ return DeclSpecContext::DSC_template_param;
+ if (Context == DeclaratorContext::TemplateArgContext ||
+ Context == DeclaratorContext::TemplateTypeArgContext)
+ return DeclSpecContext::DSC_template_type_arg;
+ if (Context == DeclaratorContext::TrailingReturnContext ||
+ Context == DeclaratorContext::TrailingReturnVarContext)
+ return DeclSpecContext::DSC_trailing;
+ if (Context == DeclaratorContext::AliasDeclContext ||
+ Context == DeclaratorContext::AliasTemplateContext)
+ return DeclSpecContext::DSC_alias_declaration;
+ return DeclSpecContext::DSC_normal;
}
/// ParseAlignArgument - Parse the argument to an alignment-specifier.
@@ -2735,7 +2747,7 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
ArgsVector ArgExprs;
ArgExprs.push_back(ArgExpr.get());
Attrs.addNew(KWName, KWLoc, nullptr, KWLoc, ArgExprs.data(), 1,
- AttributeList::AS_Keyword, EllipsisLoc);
+ ParsedAttr::AS_Keyword, EllipsisLoc);
}
/// Determine whether we're looking at something that might be a declarator
@@ -2751,7 +2763,8 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
LateParsedAttrList *LateAttrs) {
assert(DS.hasTagDefinition() && "shouldn't call this");
- bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
+ bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
+ DSContext == DeclSpecContext::DSC_top_level);
if (getLangOpts().CPlusPlus &&
Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
@@ -2845,6 +2858,17 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
return false;
}
+// Choose the apprpriate diagnostic error for why fixed point types are
+// disabled, set the previous specifier, and mark as invalid.
+static void SetupFixedPointError(const LangOptions &LangOpts,
+ const char *&PrevSpec, unsigned &DiagID,
+ bool &isInvalid) {
+ assert(!LangOpts.FixedPoint);
+ DiagID = diag::err_fixed_point_not_enabled;
+ PrevSpec = ""; // Not used by diagnostic
+ isInvalid = true;
+}
+
/// ParseDeclarationSpecifiers
/// declaration-specifiers: [C99 6.7]
/// storage-class-specifier declaration-specifiers[opt]
@@ -2885,7 +2909,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
DS.SetRangeEnd(SourceLocation());
}
- bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
+ bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
+ DSContext == DeclSpecContext::DSC_top_level);
bool AttrsLastTime = false;
ParsedAttributesWithRange attrs(AttrFactory);
// We use Sema's policy to get bool macros right.
@@ -2955,8 +2980,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Scope::FunctionPrototypeScope |
Scope::AtCatchScope)) == 0;
bool AllowNestedNameSpecifiers
- = DSContext == DSC_top_level ||
- (DSContext == DSC_class && DS.isFriendSpecified());
+ = DSContext == DeclSpecContext::DSC_top_level ||
+ (DSContext == DeclSpecContext::DSC_class && DS.isFriendSpecified());
Actions.CodeCompleteDeclSpec(getCurScope(), DS,
AllowNonIdentifiers,
@@ -2967,9 +2992,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
CCC = Sema::PCC_LocalDeclarationSpecifiers;
else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
- CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate
- : Sema::PCC_Template;
- else if (DSContext == DSC_class)
+ CCC = DSContext == DeclSpecContext::DSC_class ? Sema::PCC_MemberTemplate
+ : Sema::PCC_Template;
+ else if (DSContext == DeclSpecContext::DSC_class)
CCC = Sema::PCC_Class;
else if (CurParsedObjCImpl)
CCC = Sema::PCC_ObjCImplementation;
@@ -3013,10 +3038,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// To improve diagnostics for this case, parse the declaration as a
// constructor (and reject the extra template arguments later).
TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
- if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
+ if ((DSContext == DeclSpecContext::DSC_top_level ||
+ DSContext == DeclSpecContext::DSC_class) &&
TemplateId->Name &&
Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS) &&
- isConstructorDeclarator(/*Unqualified*/false)) {
+ isConstructorDeclarator(/*Unqualified*/ false)) {
// The user meant this to be an out-of-line constructor
// definition, but template arguments are not allowed
// there. Just allow this as a constructor; we'll
@@ -3055,7 +3081,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// Check whether this is a constructor declaration. If we're in a
// context where the identifier could be a class name, and it has the
// shape of a constructor declaration, process it as one.
- if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
+ if ((DSContext == DeclSpecContext::DSC_top_level ||
+ DSContext == DeclSpecContext::DSC_class) &&
Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
&SS) &&
isConstructorDeclarator(/*Unqualified*/ false))
@@ -3193,7 +3220,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
if (DS.isTypeAltiVecVector())
goto DoneWithDeclSpec;
- if (DSContext == DSC_objc_method_result && isObjCInstancetype()) {
+ if (DSContext == DeclSpecContext::DSC_objc_method_result &&
+ isObjCInstancetype()) {
ParsedType TypeRep = Actions.ActOnObjCInstanceType(Loc);
assert(TypeRep);
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
@@ -3206,6 +3234,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
continue;
}
+ // If we're in a context where the identifier could be a class name,
+ // check whether this is a constructor declaration.
+ if (getLangOpts().CPlusPlus && DSContext == DeclSpecContext::DSC_class &&
+ Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
+ isConstructorDeclarator(/*Unqualified*/true))
+ goto DoneWithDeclSpec;
+
ParsedType TypeRep = Actions.getTypeName(
*Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), nullptr,
false, false, nullptr, false, false,
@@ -3225,17 +3260,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
goto DoneWithDeclSpec;
}
- // If we're in a context where the identifier could be a class name,
- // check whether this is a constructor declaration.
- if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
- Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
- isConstructorDeclarator(/*Unqualified*/true))
- goto DoneWithDeclSpec;
-
// Likewise, if this is a context where the identifier could be a template
// name, check whether this is a deduction guide declaration.
if (getLangOpts().CPlusPlus17 &&
- (DSContext == DSC_class || DSContext == DSC_top_level) &&
+ (DSContext == DeclSpecContext::DSC_class ||
+ DSContext == DeclSpecContext::DSC_top_level) &&
Actions.isDeductionGuideName(getCurScope(), *Tok.getIdentifierInfo(),
Tok.getLocation()) &&
isConstructorDeclarator(/*Unqualified*/ true,
@@ -3281,7 +3310,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// If we're in a context where the template-id could be a
// constructor name or specialization, check whether this is a
// constructor declaration.
- if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
+ if (getLangOpts().CPlusPlus && DSContext == DeclSpecContext::DSC_class &&
Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
isConstructorDeclarator(TemplateId->SS.isEmpty()))
goto DoneWithDeclSpec;
@@ -3308,7 +3337,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = Tok.getLocation();
DS.getAttributes().addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc,
- nullptr, 0, AttributeList::AS_Keyword);
+ nullptr, 0, ParsedAttr::AS_Keyword);
break;
}
@@ -3351,7 +3380,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// Objective-C 'kindof' types.
case tok::kw___kindof:
DS.getAttributes().addNew(Tok.getIdentifierInfo(), Loc, nullptr, Loc,
- nullptr, 0, AttributeList::AS_Keyword);
+ nullptr, 0, ParsedAttr::AS_Keyword);
(void)ConsumeToken();
continue;
@@ -3419,6 +3448,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
case tok::kw_thread_local:
isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS_thread_local, Loc,
PrevSpec, DiagID);
+ isStorageClass = true;
break;
case tok::kw__Thread_local:
isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local,
@@ -3431,7 +3461,15 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID);
break;
case tok::kw_virtual:
- isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID);
+ // OpenCL C++ v1.0 s2.9: the virtual function qualifier is not supported.
+ if (getLangOpts().OpenCLCPlusPlus) {
+ DiagID = diag::err_openclcxx_virtual_function;
+ PrevSpec = Tok.getIdentifierInfo()->getNameStart();
+ isInvalid = true;
+ }
+ else {
+ isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID);
+ }
break;
case tok::kw_explicit:
isInvalid = DS.setFunctionSpecExplicit(Loc, PrevSpec, DiagID);
@@ -3451,7 +3489,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// friend
case tok::kw_friend:
- if (DSContext == DSC_class)
+ if (DSContext == DeclSpecContext::DSC_class)
isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
else {
PrevSpec = ""; // not actually used by the diagnostic
@@ -3535,6 +3573,29 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec,
DiagID, Policy);
break;
+ case tok::kw__Accum:
+ if (!getLangOpts().FixedPoint) {
+ SetupFixedPointError(getLangOpts(), PrevSpec, DiagID, isInvalid);
+ } else {
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_accum, Loc, PrevSpec,
+ DiagID, Policy);
+ }
+ break;
+ case tok::kw__Fract:
+ if (!getLangOpts().FixedPoint) {
+ SetupFixedPointError(getLangOpts(), PrevSpec, DiagID, isInvalid);
+ } else {
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_fract, Loc, PrevSpec,
+ DiagID, Policy);
+ }
+ break;
+ case tok::kw__Sat:
+ if (!getLangOpts().FixedPoint) {
+ SetupFixedPointError(getLangOpts(), PrevSpec, DiagID, isInvalid);
+ } else {
+ isInvalid = DS.SetTypeSpecSat(Loc, PrevSpec, DiagID);
+ }
+ break;
case tok::kw___float128:
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec,
DiagID, Policy);
@@ -3543,6 +3604,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
DiagID, Policy);
break;
+ case tok::kw_char8_t:
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char8, Loc, PrevSpec,
+ DiagID, Policy);
+ break;
case tok::kw_char16_t:
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
DiagID, Policy);
@@ -3703,11 +3768,25 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
getLangOpts());
break;
- // OpenCL qualifiers:
+ // OpenCL access qualifiers:
+ case tok::kw___read_only:
+ case tok::kw___write_only:
+ case tok::kw___read_write:
+ // OpenCL C++ 1.0 s2.2: access qualifiers are reserved keywords.
+ if (Actions.getLangOpts().OpenCLCPlusPlus) {
+ DiagID = diag::err_openclcxx_reserved;
+ PrevSpec = Tok.getIdentifierInfo()->getNameStart();
+ isInvalid = true;
+ }
+ ParseOpenCLQualifiers(DS.getAttributes());
+ break;
+
+ // OpenCL address space qualifiers:
case tok::kw___generic:
// generic address space is introduced only in OpenCL v2.0
// see OpenCL C Spec v2.0 s6.5.5
- if (Actions.getLangOpts().OpenCLVersion < 200) {
+ if (Actions.getLangOpts().OpenCLVersion < 200 &&
+ !Actions.getLangOpts().OpenCLCPlusPlus) {
DiagID = diag::err_opencl_unknown_type_specifier;
PrevSpec = Tok.getIdentifierInfo()->getNameStart();
isInvalid = true;
@@ -3718,9 +3797,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
case tok::kw___global:
case tok::kw___local:
case tok::kw___constant:
- case tok::kw___read_only:
- case tok::kw___write_only:
- case tok::kw___read_write:
ParseOpenCLQualifiers(DS.getAttributes());
break;
@@ -3758,18 +3834,17 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Diag(Tok, DiagID)
<< PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
else if (DiagID == diag::err_opencl_unknown_type_specifier) {
- const int OpenCLVer = getLangOpts().OpenCLVersion;
- std::string VerSpec = llvm::to_string(OpenCLVer / 100) +
- std::string (".") +
- llvm::to_string((OpenCLVer % 100) / 10);
- Diag(Tok, DiagID) << VerSpec << PrevSpec << isStorageClass;
+ Diag(Tok, DiagID) << getLangOpts().OpenCLCPlusPlus
+ << getLangOpts().getOpenCLVersionTuple().getAsString()
+ << PrevSpec << isStorageClass;
} else
Diag(Tok, DiagID) << PrevSpec;
}
DS.SetRangeEnd(Tok.getLocation());
if (DiagID != diag::err_bool_redeclaration)
- ConsumeToken();
+ // After an error the next token can be an annotation token.
+ ConsumeAnyToken();
AttrsLastTime = false;
}
@@ -3878,7 +3953,7 @@ void Parser::ParseStructDeclaration(
///
void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
unsigned TagType, Decl *TagDecl) {
- PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
+ PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,
"parsing struct/union body");
assert(!getLangOpts().CPlusPlus && "C++ declarations not supported");
@@ -3984,10 +4059,8 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
// If attributes exist after struct contents, parse them.
MaybeParseGNUAttributes(attrs);
- Actions.ActOnFields(getCurScope(),
- RecordLoc, TagDecl, FieldDecls,
- T.getOpenLocation(), T.getCloseLocation(),
- attrs.getList());
+ Actions.ActOnFields(getCurScope(), RecordLoc, TagDecl, FieldDecls,
+ T.getOpenLocation(), T.getCloseLocation(), attrs);
StructScope.Exit();
Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange());
}
@@ -4070,7 +4143,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
// Enum definitions should not be parsed in a trailing-return-type.
- bool AllowDeclaration = DSC != DSC_trailing;
+ bool AllowDeclaration = DSC != DeclSpecContext::DSC_trailing;
bool AllowFixedUnderlyingType = AllowDeclaration &&
(getLangOpts().CPlusPlus11 || getLangOpts().MicrosoftExt ||
@@ -4296,14 +4369,14 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
bool IsDependent = false;
const char *PrevSpec = nullptr;
unsigned DiagID;
- Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
- StartLoc, SS, Name, NameLoc, attrs.getList(),
- AS, DS.getModulePrivateSpecLoc(), TParams,
- Owned, IsDependent, ScopedEnumKWLoc,
- IsScopedUsingClassTag, BaseType,
- DSC == DSC_type_specifier,
- DSC == DSC_template_param ||
- DSC == DSC_template_type_arg, &SkipBody);
+ Decl *TagDecl = Actions.ActOnTag(
+ getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS, Name, NameLoc,
+ attrs, AS, DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
+ ScopedEnumKWLoc, IsScopedUsingClassTag, BaseType,
+ DSC == DeclSpecContext::DSC_type_specifier,
+ DSC == DeclSpecContext::DSC_template_param ||
+ DSC == DeclSpecContext::DSC_template_type_arg,
+ &SkipBody);
if (SkipBody.ShouldSkip) {
assert(TUK == Sema::TUK_Definition && "can only skip a definition");
@@ -4440,8 +4513,8 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
// Install the enumerator constant into EnumDecl.
Decl *EnumConstDecl = Actions.ActOnEnumConstant(
- getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident,
- attrs.getList(), EqualLoc, AssignedVal.get());
+ getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
+ EqualLoc, AssignedVal.get());
EnumAvailabilityDiags.back().done();
EnumConstantDecls.push_back(EnumConstDecl);
@@ -4493,10 +4566,8 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
ParsedAttributes attrs(AttrFactory);
MaybeParseGNUAttributes(attrs);
- Actions.ActOnEnumBody(StartLoc, T.getRange(),
- EnumDecl, EnumConstantDecls,
- getCurScope(),
- attrs.getList());
+ Actions.ActOnEnumBody(StartLoc, T.getRange(), EnumDecl, EnumConstantDecls,
+ getCurScope(), attrs);
// Now handle enum constant availability diagnostics.
assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
@@ -4540,12 +4611,15 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
case tok::kw_void:
case tok::kw_char:
case tok::kw_wchar_t:
+ case tok::kw_char8_t:
case tok::kw_char16_t:
case tok::kw_char32_t:
case tok::kw_int:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
+ case tok::kw__Accum:
+ case tok::kw__Fract:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_bool:
@@ -4616,12 +4690,15 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw_void:
case tok::kw_char:
case tok::kw_wchar_t:
+ case tok::kw_char8_t:
case tok::kw_char16_t:
case tok::kw_char32_t:
case tok::kw_int:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
+ case tok::kw__Accum:
+ case tok::kw__Fract:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_bool:
@@ -4645,6 +4722,7 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw_const:
case tok::kw_volatile:
case tok::kw_restrict:
+ case tok::kw__Sat:
// Debugger support.
case tok::kw___unknown_anytype:
@@ -4772,6 +4850,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
case tok::kw_void:
case tok::kw_char:
case tok::kw_wchar_t:
+ case tok::kw_char8_t:
case tok::kw_char16_t:
case tok::kw_char32_t:
@@ -4779,6 +4858,8 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
+ case tok::kw__Accum:
+ case tok::kw__Fract:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_bool:
@@ -4800,6 +4881,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
case tok::kw_const:
case tok::kw_volatile:
case tok::kw_restrict:
+ case tok::kw__Sat:
// function-specifier
case tok::kw_inline:
@@ -5089,7 +5171,7 @@ void Parser::ParseTypeQualifierListOpt(
getLangOpts());
break;
case tok::kw___uptr:
- // GNU libc headers in C mode use '__uptr' as an identifer which conflicts
+ // GNU libc headers in C mode use '__uptr' as an identifier which conflicts
// with the MS modifier keyword.
if ((AttrReqs & AR_DeclspecAttributesParsed) && !getLangOpts().CPlusPlus &&
IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi)) {
@@ -5129,7 +5211,7 @@ void Parser::ParseTypeQualifierListOpt(
// Objective-C 'kindof' types.
case tok::kw___kindof:
DS.getAttributes().addNew(Tok.getIdentifierInfo(), Loc, nullptr, Loc,
- nullptr, 0, AttributeList::AS_Keyword);
+ nullptr, 0, ParsedAttr::AS_Keyword);
(void)ConsumeToken();
continue;
@@ -5175,7 +5257,7 @@ void Parser::ParseDeclarator(Declarator &D) {
}
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang,
- unsigned TheContext) {
+ DeclaratorContext TheContext) {
if (Kind == tok::star || Kind == tok::caret)
return true;
@@ -5194,8 +5276,9 @@ static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang,
// (The same thing can in theory happen after a trailing-return-type, but
// since those are a C++11 feature, there is no rejects-valid issue there.)
if (Kind == tok::ampamp)
- return Lang.CPlusPlus11 || (TheContext != Declarator::ConversionIdContext &&
- TheContext != Declarator::CXXNewContext);
+ return Lang.CPlusPlus11 ||
+ (TheContext != DeclaratorContext::ConversionIdContext &&
+ TheContext != DeclaratorContext::CXXNewContext);
return false;
}
@@ -5249,8 +5332,9 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
(Tok.is(tok::identifier) &&
(NextToken().is(tok::coloncolon) || NextToken().is(tok::less))) ||
Tok.is(tok::annot_cxxscope))) {
- bool EnteringContext = D.getContext() == Declarator::FileContext ||
- D.getContext() == Declarator::MemberContext;
+ bool EnteringContext =
+ D.getContext() == DeclaratorContext::FileContext ||
+ D.getContext() == DeclaratorContext::MemberContext;
CXXScopeSpec SS;
ParseOptionalCXXScopeSpecifier(SS, nullptr, EnteringContext);
@@ -5278,10 +5362,10 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
// Sema will have to catch (syntactically invalid) pointers into global
// scope. It has to catch pointers into namespace scope anyway.
- D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
- DS.getLocEnd()),
- DS.getAttributes(),
- /* Don't replace range end. */SourceLocation());
+ D.AddTypeInfo(DeclaratorChunk::getMemberPointer(
+ SS, DS.getTypeQualifiers(), DS.getLocEnd()),
+ std::move(DS.getAttributes()),
+ /* Don't replace range end. */ SourceLocation());
return;
}
}
@@ -5294,7 +5378,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
D.AddTypeInfo(
DeclaratorChunk::getPipe(DS.getTypeQualifiers(), DS.getPipeLoc()),
- DS.getAttributes(), SourceLocation());
+ std::move(DS.getAttributes()), SourceLocation());
}
// Not a pointer, C++ reference, or block.
@@ -5316,9 +5400,9 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
// GNU attributes are not allowed here in a new-type-id, but Declspec and
// C++11 attributes are allowed.
unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
- ((D.getContext() != Declarator::CXXNewContext)
- ? AR_GNUAttributesParsed
- : AR_GNUAttributesParsedAndRejected);
+ ((D.getContext() != DeclaratorContext::CXXNewContext)
+ ? AR_GNUAttributesParsed
+ : AR_GNUAttributesParsedAndRejected);
ParseTypeQualifierListOpt(DS, Reqs, true, !D.mayOmitIdentifier());
D.ExtendWithDeclSpec(DS);
@@ -5326,20 +5410,16 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
ParseDeclaratorInternal(D, DirectDeclParser);
if (Kind == tok::star)
// Remember that we parsed a pointer type, and remember the type-quals.
- D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
- DS.getConstSpecLoc(),
- DS.getVolatileSpecLoc(),
- DS.getRestrictSpecLoc(),
- DS.getAtomicSpecLoc(),
- DS.getUnalignedSpecLoc()),
- DS.getAttributes(),
- SourceLocation());
+ D.AddTypeInfo(DeclaratorChunk::getPointer(
+ DS.getTypeQualifiers(), Loc, DS.getConstSpecLoc(),
+ DS.getVolatileSpecLoc(), DS.getRestrictSpecLoc(),
+ DS.getAtomicSpecLoc(), DS.getUnalignedSpecLoc()),
+ std::move(DS.getAttributes()), SourceLocation());
else
// Remember that we parsed a Block type, and remember the type-quals.
- D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
- Loc),
- DS.getAttributes(),
- SourceLocation());
+ D.AddTypeInfo(
+ DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), Loc),
+ std::move(DS.getAttributes()), SourceLocation());
} else {
// Is a reference
DeclSpec DS(AttrFactory);
@@ -5394,8 +5474,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
// Remember that we parsed a reference type.
D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
Kind == tok::amp),
- DS.getAttributes(),
- SourceLocation());
+ std::move(DS.getAttributes()), SourceLocation());
}
}
@@ -5470,15 +5549,16 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
// Don't parse FOO:BAR as if it were a typo for FOO::BAR inside a class, in
// this context it is a bitfield. Also in range-based for statement colon
// may delimit for-range-declaration.
- ColonProtectionRAIIObject X(*this,
- D.getContext() == Declarator::MemberContext ||
- (D.getContext() == Declarator::ForContext &&
- getLangOpts().CPlusPlus11));
+ ColonProtectionRAIIObject X(
+ *this, D.getContext() == DeclaratorContext::MemberContext ||
+ (D.getContext() == DeclaratorContext::ForContext &&
+ getLangOpts().CPlusPlus11));
// ParseDeclaratorInternal might already have parsed the scope.
if (D.getCXXScopeSpec().isEmpty()) {
- bool EnteringContext = D.getContext() == Declarator::FileContext ||
- D.getContext() == Declarator::MemberContext;
+ bool EnteringContext =
+ D.getContext() == DeclaratorContext::FileContext ||
+ D.getContext() == DeclaratorContext::MemberContext;
ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), nullptr,
EnteringContext);
}
@@ -5507,9 +5587,9 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
// been expanded or contains auto; otherwise, it is parsed as part of the
// parameter-declaration-clause.
if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
- !((D.getContext() == Declarator::PrototypeContext ||
- D.getContext() == Declarator::LambdaExprParameterContext ||
- D.getContext() == Declarator::BlockLiteralContext) &&
+ !((D.getContext() == DeclaratorContext::PrototypeContext ||
+ D.getContext() == DeclaratorContext::LambdaExprParameterContext ||
+ D.getContext() == DeclaratorContext::BlockLiteralContext) &&
NextToken().is(tok::r_paren) &&
!D.hasGroupingParens() &&
!Actions.containsUnexpandedParameterPacks(D) &&
@@ -5541,22 +5621,22 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
AllowDeductionGuide = false;
} else if (D.getCXXScopeSpec().isSet()) {
AllowConstructorName =
- (D.getContext() == Declarator::FileContext ||
- D.getContext() == Declarator::MemberContext);
+ (D.getContext() == DeclaratorContext::FileContext ||
+ D.getContext() == DeclaratorContext::MemberContext);
AllowDeductionGuide = false;
} else {
- AllowConstructorName = (D.getContext() == Declarator::MemberContext);
+ AllowConstructorName =
+ (D.getContext() == DeclaratorContext::MemberContext);
AllowDeductionGuide =
- (D.getContext() == Declarator::FileContext ||
- D.getContext() == Declarator::MemberContext);
+ (D.getContext() == DeclaratorContext::FileContext ||
+ D.getContext() == DeclaratorContext::MemberContext);
}
- SourceLocation TemplateKWLoc;
bool HadScope = D.getCXXScopeSpec().isValid();
if (ParseUnqualifiedId(D.getCXXScopeSpec(),
/*EnteringContext=*/true,
/*AllowDestructorName=*/true, AllowConstructorName,
- AllowDeductionGuide, nullptr, TemplateKWLoc,
+ AllowDeductionGuide, nullptr, nullptr,
D.getName()) ||
// Once we're past the identifier, if the scope was bad, mark the
// whole declarator bad.
@@ -5604,15 +5684,16 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
// An identifier within parens is unlikely to be intended to be anything
// other than a name being "declared".
DiagnoseIdentifier = true;
- else if (D.getContext() == Declarator::TemplateTypeArgContext)
+ else if (D.getContext() == DeclaratorContext::TemplateArgContext)
// T<int N> is an accidental identifier; T<int N indicates a missing '>'.
DiagnoseIdentifier =
NextToken().isOneOf(tok::comma, tok::greater, tok::greatergreater);
- else if (D.getContext() == Declarator::AliasDeclContext ||
- D.getContext() == Declarator::AliasTemplateContext)
+ else if (D.getContext() == DeclaratorContext::AliasDeclContext ||
+ D.getContext() == DeclaratorContext::AliasTemplateContext)
// The most likely error is that the ';' was forgotten.
DiagnoseIdentifier = NextToken().isOneOf(tok::comma, tok::semi);
- else if (D.getContext() == Declarator::TrailingReturnContext &&
+ else if ((D.getContext() == DeclaratorContext::TrailingReturnContext ||
+ D.getContext() == DeclaratorContext::TrailingReturnVarContext) &&
!isCXX11VirtSpecifier(Tok))
DiagnoseIdentifier = NextToken().isOneOf(
tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
@@ -5626,6 +5707,18 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
}
if (Tok.is(tok::l_paren)) {
+ // If this might be an abstract-declarator followed by a direct-initializer,
+ // check whether this is a valid declarator chunk. If it can't be, assume
+ // that it's an initializer instead.
+ if (D.mayOmitIdentifier() && D.mayBeFollowedByCXXDirectInit()) {
+ RevertingTentativeParsingAction PA(*this);
+ if (TryParseDeclarator(true, D.mayHaveIdentifier(), true) ==
+ TPResult::False) {
+ D.SetIdentifier(nullptr, Tok.getLocation());
+ goto PastIdentifier;
+ }
+ }
+
// direct-declarator: '(' declarator ')'
// direct-declarator: '(' attributes declarator ')'
// Example: 'char (*X)' or 'int (*XX)(void)'
@@ -5659,7 +5752,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
LLVM_BUILTIN_TRAP;
if (Tok.is(tok::l_square))
return ParseMisplacedBracketDeclarator(D);
- if (D.getContext() == Declarator::MemberContext) {
+ if (D.getContext() == DeclaratorContext::MemberContext) {
// Objective-C++: Detect C++ keywords and try to prevent further errors by
// treating these keyword as valid member names.
if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus &&
@@ -5889,9 +5982,9 @@ void Parser::ParseParenDeclarator(Declarator &D) {
ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
// Match the ')'.
T.consumeClose();
- D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
- T.getCloseLocation()),
- attrs, T.getCloseLocation());
+ D.AddTypeInfo(
+ DeclaratorChunk::getParen(T.getOpenLocation(), T.getCloseLocation()),
+ std::move(attrs), T.getCloseLocation());
D.setGroupingParens(hadGroupingParens);
@@ -6042,9 +6135,9 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
bool IsCXX11MemberFunction =
getLangOpts().CPlusPlus11 &&
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
- (D.getContext() == Declarator::MemberContext
+ (D.getContext() == DeclaratorContext::MemberContext
? !D.getDeclSpec().isFriendSpecified()
- : D.getContext() == Declarator::FileContext &&
+ : D.getContext() == DeclaratorContext::FileContext &&
D.getCXXScopeSpec().isValid() &&
Actions.CurContext->isRecord());
Sema::CXXThisScopeRAII ThisScope(Actions,
@@ -6096,7 +6189,8 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
StartLoc = D.getDeclSpec().getTypeSpecTypeLoc();
LocalEndLoc = Tok.getLocation();
SourceRange Range;
- TrailingReturnType = ParseTrailingReturnType(Range);
+ TrailingReturnType =
+ ParseTrailingReturnType(Range, D.mayBeFollowedByCXXDirectInit());
EndLoc = Range.getEnd();
}
} else if (standardAttributesAllowed()) {
@@ -6120,28 +6214,19 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
}
// Remember that we parsed a function type, and remember the attributes.
- D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
- IsAmbiguous,
- LParenLoc,
- ParamInfo.data(), ParamInfo.size(),
- EllipsisLoc, RParenLoc,
- DS.getTypeQualifiers(),
- RefQualifierIsLValueRef,
- RefQualifierLoc, ConstQualifierLoc,
- VolatileQualifierLoc,
- RestrictQualifierLoc,
- /*MutableLoc=*/SourceLocation(),
- ESpecType, ESpecRange,
- DynamicExceptions.data(),
- DynamicExceptionRanges.data(),
- DynamicExceptions.size(),
- NoexceptExpr.isUsable() ?
- NoexceptExpr.get() : nullptr,
- ExceptionSpecTokens,
- DeclsInPrototype,
- StartLoc, LocalEndLoc, D,
- TrailingReturnType),
- FnAttrs, EndLoc);
+ D.AddTypeInfo(DeclaratorChunk::getFunction(
+ HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
+ ParamInfo.size(), EllipsisLoc, RParenLoc,
+ DS.getTypeQualifiers(), RefQualifierIsLValueRef,
+ RefQualifierLoc, ConstQualifierLoc, VolatileQualifierLoc,
+ RestrictQualifierLoc,
+ /*MutableLoc=*/SourceLocation(), ESpecType, ESpecRange,
+ DynamicExceptions.data(), DynamicExceptionRanges.data(),
+ DynamicExceptions.size(),
+ NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,
+ ExceptionSpecTokens, DeclsInPrototype, StartLoc,
+ LocalEndLoc, D, TrailingReturnType),
+ std::move(FnAttrs), EndLoc);
}
/// ParseRefQualifier - Parses a member function ref-qualifier. Returns
@@ -6309,10 +6394,10 @@ void Parser::ParseParameterDeclarationClause(
// Parse the declarator. This is "PrototypeContext" or
// "LambdaExprParameterContext", because we must accept either
// 'declarator' or 'abstract-declarator' here.
- Declarator ParmDeclarator(DS,
- D.getContext() == Declarator::LambdaExprContext ?
- Declarator::LambdaExprParameterContext :
- Declarator::PrototypeContext);
+ Declarator ParmDeclarator(
+ DS, D.getContext() == DeclaratorContext::LambdaExprContext
+ ? DeclaratorContext::LambdaExprParameterContext
+ : DeclaratorContext::PrototypeContext);
ParseDeclarator(ParmDeclarator);
// Parse GNU attributes, if present.
@@ -6355,7 +6440,7 @@ void Parser::ParseParameterDeclarationClause(
SourceLocation EqualLoc = Tok.getLocation();
// Parse the default argument
- if (D.getContext() == Declarator::MemberContext) {
+ if (D.getContext() == DeclaratorContext::MemberContext) {
// If we're inside a class definition, cache the tokens
// corresponding to the default argument. We'll actually parse
// them when we see the end of the class definition.
@@ -6463,7 +6548,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, nullptr,
T.getOpenLocation(),
T.getCloseLocation()),
- attrs, T.getCloseLocation());
+ std::move(attrs), T.getCloseLocation());
return;
} else if (Tok.getKind() == tok::numeric_constant &&
GetLookAheadToken(1).is(tok::r_square)) {
@@ -6476,11 +6561,10 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
MaybeParseCXX11Attributes(attrs);
// Remember that we parsed a array type, and remember its features.
- D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false,
- ExprRes.get(),
+ D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, ExprRes.get(),
T.getOpenLocation(),
T.getCloseLocation()),
- attrs, T.getCloseLocation());
+ std::move(attrs), T.getCloseLocation());
return;
} else if (Tok.getKind() == tok::code_completion) {
Actions.CodeCompleteBracketDeclarator(getCurScope());
@@ -6553,12 +6637,11 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
MaybeParseCXX11Attributes(DS.getAttributes());
// Remember that we parsed a array type, and remember its features.
- D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
- StaticLoc.isValid(), isStar,
- NumElements.get(),
- T.getOpenLocation(),
- T.getCloseLocation()),
- DS.getAttributes(), T.getCloseLocation());
+ D.AddTypeInfo(
+ DeclaratorChunk::getArray(DS.getTypeQualifiers(), StaticLoc.isValid(),
+ isStar, NumElements.get(), T.getOpenLocation(),
+ T.getCloseLocation()),
+ std::move(DS.getAttributes()), T.getCloseLocation());
}
/// Diagnose brackets before an identifier.
@@ -6610,18 +6693,15 @@ void Parser::ParseMisplacedBracketDeclarator(Declarator &D) {
if (NeedParens) {
// Create a DeclaratorChunk for the inserted parens.
- ParsedAttributes attrs(AttrFactory);
SourceLocation EndLoc = PP.getLocForEndOfToken(D.getLocEnd());
- D.AddTypeInfo(DeclaratorChunk::getParen(SuggestParenLoc, EndLoc), attrs,
+ D.AddTypeInfo(DeclaratorChunk::getParen(SuggestParenLoc, EndLoc),
SourceLocation());
}
// Adding back the bracket info to the end of the Declarator.
for (unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
- ParsedAttributes attrs(AttrFactory);
- attrs.set(Chunk.Common.AttrList);
- D.AddTypeInfo(Chunk, attrs, SourceLocation());
+ D.AddTypeInfo(Chunk, SourceLocation());
}
// The missing identifier would have been diagnosed in ParseDirectDeclarator.
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 44e7a3512098..7c4c83d032b6 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -14,6 +14,7 @@
#include "clang/Parse/Parser.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/Attributes.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/OperatorKinds.h"
@@ -22,7 +23,6 @@
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ParsedTemplate.h"
-#include "clang/Sema/PrettyDeclStackTrace.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/ADT/SmallString.h"
@@ -55,7 +55,7 @@ using namespace clang;
/// namespace-alias-definition: [C++ 7.3.2: namespace.alias]
/// 'namespace' identifier '=' qualified-namespace-specifier ';'
///
-Parser::DeclGroupPtrTy Parser::ParseNamespace(unsigned Context,
+Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context,
SourceLocation &DeclEnd,
SourceLocation InlineLoc) {
assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
@@ -183,13 +183,12 @@ Parser::DeclGroupPtrTy Parser::ParseNamespace(unsigned Context,
ParseScope NamespaceScope(this, Scope::DeclScope);
UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;
- Decl *NamespcDecl =
- Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc,
- IdentLoc, Ident, T.getOpenLocation(),
- attrs.getList(), ImplicitUsingDirectiveDecl);
+ Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(
+ getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident,
+ T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl);
- PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
- "parsing namespace");
+ PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl,
+ NamespaceLoc, "parsing namespace");
// Parse the contents of the namespace. This includes parsing recovery on
// any improperly nested namespaces.
@@ -233,11 +232,10 @@ void Parser::ParseInnerNamespace(std::vector<SourceLocation> &IdentLoc,
// desugaring it here.
ParseScope NamespaceScope(this, Scope::DeclScope);
UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;
- Decl *NamespcDecl =
- Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(),
- NamespaceLoc[index], IdentLoc[index],
- Ident[index], Tracker.getOpenLocation(),
- attrs.getList(), ImplicitUsingDirectiveDecl);
+ Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(
+ getCurScope(), SourceLocation(), NamespaceLoc[index], IdentLoc[index],
+ Ident[index], Tracker.getOpenLocation(), attrs,
+ ImplicitUsingDirectiveDecl);
assert(!ImplicitUsingDirectiveDecl &&
"nested namespace definition cannot define anonymous namespace");
@@ -307,7 +305,7 @@ Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
/// 'extern' string-literal '{' declaration-seq[opt] '}'
/// 'extern' string-literal declaration
///
-Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
+Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
assert(isTokenStringLiteral() && "Not a string literal!");
ExprResult Lang = ParseStringLiteralExpression(false);
@@ -434,7 +432,7 @@ Decl *Parser::ParseExportDeclaration() {
/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
/// using-directive. Assumes that current token is 'using'.
Parser::DeclGroupPtrTy
-Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
+Parser::ParseUsingDirectiveOrDeclaration(DeclaratorContext Context,
const ParsedTemplateInfo &TemplateInfo,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs) {
@@ -482,7 +480,7 @@ Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
/// namespace-name attributes[opt] ;
///
-Decl *Parser::ParseUsingDirective(unsigned Context,
+Decl *Parser::ParseUsingDirective(DeclaratorContext Context,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
ParsedAttributes &attrs) {
@@ -543,7 +541,7 @@ Decl *Parser::ParseUsingDirective(unsigned Context,
SkipUntil(tok::semi);
return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
- IdentLoc, NamespcName, attrs.getList());
+ IdentLoc, NamespcName, attrs);
}
/// Parse a using-declarator (or the identifier in a C++11 alias-declaration).
@@ -551,7 +549,8 @@ Decl *Parser::ParseUsingDirective(unsigned Context,
/// using-declarator:
/// 'typename'[opt] nested-name-specifier unqualified-id
///
-bool Parser::ParseUsingDeclarator(unsigned Context, UsingDeclarator &D) {
+bool Parser::ParseUsingDeclarator(DeclaratorContext Context,
+ UsingDeclarator &D) {
D.clear();
// Ignore optional 'typename'.
@@ -582,7 +581,8 @@ bool Parser::ParseUsingDeclarator(unsigned Context, UsingDeclarator &D) {
// or the simple-template-id's template-name in the last component of the
// nested-name-specifier, the name is [...] considered to name the
// constructor.
- if (getLangOpts().CPlusPlus11 && Context == Declarator::MemberContext &&
+ if (getLangOpts().CPlusPlus11 &&
+ Context == DeclaratorContext::MemberContext &&
Tok.is(tok::identifier) &&
(NextToken().is(tok::semi) || NextToken().is(tok::comma) ||
NextToken().is(tok::ellipsis)) &&
@@ -600,7 +600,7 @@ bool Parser::ParseUsingDeclarator(unsigned Context, UsingDeclarator &D) {
/*AllowConstructorName=*/!(Tok.is(tok::identifier) &&
NextToken().is(tok::equal)),
/*AllowDeductionGuide=*/false,
- nullptr, D.TemplateKWLoc, D.Name))
+ nullptr, nullptr, D.Name))
return true;
}
@@ -629,7 +629,7 @@ bool Parser::ParseUsingDeclarator(unsigned Context, UsingDeclarator &D) {
/// 'using' identifier attribute-specifier-seq[opt] = type-id ;
///
Parser::DeclGroupPtrTy
-Parser::ParseUsingDeclaration(unsigned Context,
+Parser::ParseUsingDeclaration(DeclaratorContext Context,
const ParsedTemplateInfo &TemplateInfo,
SourceLocation UsingLoc, SourceLocation &DeclEnd,
AccessSpecifier AS) {
@@ -699,7 +699,7 @@ Parser::ParseUsingDeclaration(unsigned Context,
// "typename" keyword is allowed for identifiers only,
// because it may be a type definition.
if (D.TypenameLoc.isValid() &&
- D.Name.getKind() != UnqualifiedId::IK_Identifier) {
+ D.Name.getKind() != UnqualifiedIdKind::IK_Identifier) {
Diag(D.Name.getSourceRange().getBegin(),
diag::err_typename_identifiers_only)
<< FixItHint::CreateRemoval(SourceRange(D.TypenameLoc));
@@ -709,7 +709,7 @@ Parser::ParseUsingDeclaration(unsigned Context,
Decl *UD = Actions.ActOnUsingDeclaration(getCurScope(), AS, UsingLoc,
D.TypenameLoc, D.SS, D.Name,
- D.EllipsisLoc, Attrs.getList());
+ D.EllipsisLoc, Attrs);
if (UD)
DeclsInGroup.push_back(UD);
}
@@ -753,7 +753,7 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
// Type alias templates cannot be specialized.
int SpecKind = -1;
if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
- D.Name.getKind() == UnqualifiedId::IK_TemplateId)
+ D.Name.getKind() == UnqualifiedIdKind::IK_TemplateId)
SpecKind = 0;
if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
SpecKind = 1;
@@ -773,7 +773,7 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
}
// Name must be an identifier.
- if (D.Name.getKind() != UnqualifiedId::IK_Identifier) {
+ if (D.Name.getKind() != UnqualifiedIdKind::IK_Identifier) {
Diag(D.Name.StartLocation, diag::err_alias_declaration_not_identifier);
// No removal fixit: can't recover from this.
SkipUntil(tok::semi);
@@ -791,11 +791,11 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
<< FixItHint::CreateRemoval(SourceRange(D.EllipsisLoc));
Decl *DeclFromDeclSpec = nullptr;
- TypeResult TypeAlias =
- ParseTypeName(nullptr,
- TemplateInfo.Kind ? Declarator::AliasTemplateContext
- : Declarator::AliasDeclContext,
- AS, &DeclFromDeclSpec, &Attrs);
+ TypeResult TypeAlias = ParseTypeName(
+ nullptr,
+ TemplateInfo.Kind ? DeclaratorContext::AliasTemplateContext
+ : DeclaratorContext::AliasDeclContext,
+ AS, &DeclFromDeclSpec, &Attrs);
if (OwnedType)
*OwnedType = DeclFromDeclSpec;
@@ -811,8 +811,8 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
TemplateParams ? TemplateParams->data() : nullptr,
TemplateParams ? TemplateParams->size() : 0);
return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
- UsingLoc, D.Name, Attrs.getList(),
- TypeAlias, DeclFromDeclSpec);
+ UsingLoc, D.Name, Attrs, TypeAlias,
+ DeclFromDeclSpec);
}
/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
@@ -940,7 +940,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
// The operand of the decltype specifier is an unevaluated operand.
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
- /*IsDecltype=*/true);
+ Sema::ExpressionEvaluationContextRecord::EK_Decltype);
Result =
Actions.CorrectDelayedTyposInExpr(ParseExpression(), [](Expr *E) {
return E->hasPlaceholderType() ? ExprError() : E;
@@ -1094,7 +1094,7 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
EndLocation = ParseDecltypeSpecifier(DS);
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
}
@@ -1195,7 +1195,7 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type,
Actions.getASTContext().getPrintingPolicy());
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
}
@@ -1206,7 +1206,7 @@ void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- AttributeList::AS_Keyword);
+ ParsedAttr::AS_Keyword);
}
}
@@ -1612,14 +1612,15 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// new struct s;
// or
// &T::operator struct s;
- // For these, DSC is DSC_type_specifier or DSC_alias_declaration.
+ // For these, DSC is DeclSpecContext::DSC_type_specifier or
+ // DeclSpecContext::DSC_alias_declaration.
// If there are attributes after class name, parse them.
MaybeParseCXX11Attributes(Attributes);
const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
Sema::TagUseKind TUK;
- if (DSC == DSC_trailing)
+ if (DSC == DeclSpecContext::DSC_trailing)
TUK = Sema::TUK_Reference;
else if (Tok.is(tok::l_brace) ||
(getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
@@ -1749,24 +1750,16 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// This is an explicit instantiation of a class template.
ProhibitAttributes(attrs);
- TagOrTempResult
- = Actions.ActOnExplicitInstantiation(getCurScope(),
- TemplateInfo.ExternLoc,
- TemplateInfo.TemplateLoc,
- TagType,
- StartLoc,
- SS,
- TemplateId->Template,
- TemplateId->TemplateNameLoc,
- TemplateId->LAngleLoc,
- TemplateArgsPtr,
- TemplateId->RAngleLoc,
- attrs.getList());
-
- // Friend template-ids are treated as references unless
- // they have template headers, in which case they're ill-formed
- // (FIXME: "template <class T> friend class A<T>::B<int>;").
- // We diagnose this error in ActOnClassTemplateSpecialization.
+ TagOrTempResult = Actions.ActOnExplicitInstantiation(
+ getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
+ TagType, StartLoc, SS, TemplateId->Template,
+ TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr,
+ TemplateId->RAngleLoc, attrs);
+
+ // Friend template-ids are treated as references unless
+ // they have template headers, in which case they're ill-formed
+ // (FIXME: "template <class T> friend class A<T>::B<int>;").
+ // We diagnose this error in ActOnClassTemplateSpecialization.
} else if (TUK == Sema::TUK_Reference ||
(TUK == Sema::TUK_Friend &&
TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
@@ -1822,7 +1815,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// Build the class template specialization.
TagOrTempResult = Actions.ActOnClassTemplateSpecialization(
getCurScope(), TagType, TUK, StartLoc, DS.getModulePrivateSpecLoc(),
- *TemplateId, attrs.getList(),
+ *TemplateId, attrs,
MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0]
: nullptr,
TemplateParams ? TemplateParams->size() : 0),
@@ -1837,24 +1830,18 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
//
ProhibitAttributes(attrs);
- TagOrTempResult
- = Actions.ActOnExplicitInstantiation(getCurScope(),
- TemplateInfo.ExternLoc,
- TemplateInfo.TemplateLoc,
- TagType, StartLoc, SS, Name,
- NameLoc, attrs.getList());
+ TagOrTempResult = Actions.ActOnExplicitInstantiation(
+ getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
+ TagType, StartLoc, SS, Name, NameLoc, attrs);
} else if (TUK == Sema::TUK_Friend &&
TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
ProhibitAttributes(attrs);
- TagOrTempResult =
- Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
- TagType, StartLoc, SS,
- Name, NameLoc, attrs.getList(),
- MultiTemplateParamsArg(
- TemplateParams? &(*TemplateParams)[0]
- : nullptr,
- TemplateParams? TemplateParams->size() : 0));
+ TagOrTempResult = Actions.ActOnTemplatedFriendTag(
+ getCurScope(), DS.getFriendSpecLoc(), TagType, StartLoc, SS, Name,
+ NameLoc, attrs,
+ MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr,
+ TemplateParams ? TemplateParams->size() : 0));
} else {
if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition)
ProhibitAttributes(attrs);
@@ -1881,15 +1868,14 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
// Declaration or definition of a class type
- TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
- SS, Name, NameLoc, attrs.getList(), AS,
- DS.getModulePrivateSpecLoc(),
- TParams, Owned, IsDependent,
- SourceLocation(), false,
- clang::TypeResult(),
- DSC == DSC_type_specifier,
- DSC == DSC_template_param ||
- DSC == DSC_template_type_arg, &SkipBody);
+ TagOrTempResult = Actions.ActOnTag(
+ getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, attrs, AS,
+ DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
+ SourceLocation(), false, clang::TypeResult(),
+ DSC == DeclSpecContext::DSC_type_specifier,
+ DSC == DeclSpecContext::DSC_template_param ||
+ DSC == DeclSpecContext::DSC_template_type_arg,
+ &SkipBody);
// If ActOnTag said the type was dependent, try again with the
// less common call.
@@ -1927,7 +1913,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
if (!TagOrTempResult.isInvalid())
// Delayed processing of attributes.
- Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs.getList());
+ Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs);
const char *PrevSpec = nullptr;
unsigned DiagID;
@@ -2107,7 +2093,7 @@ AccessSpecifier Parser::getAccessSpecifierIfPresent() const {
}
}
-/// \brief If the given declarator has any parts for which parsing has to be
+/// If the given declarator has any parts for which parsing has to be
/// delayed, e.g., default arguments or an exception-specification, create a
/// late-parsed method declaration record to handle the parsing at the end of
/// the class definition.
@@ -2247,7 +2233,7 @@ bool Parser::isCXX11FinalKeyword() const {
Specifier == VirtSpecifiers::VS_Sealed;
}
-/// \brief Parse a C++ member-declarator up to, but not including, the optional
+/// Parse a C++ member-declarator up to, but not including, the optional
/// brace-or-equal-initializer or pure-specifier.
bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
Declarator &DeclaratorInfo, VirtSpecifiers &VS, ExprResult &BitfieldSize,
@@ -2298,12 +2284,10 @@ bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
if (!VS.isUnset()) {
// If we saw any GNU-style attributes that are known to GCC followed by a
// virt-specifier, issue a GCC-compat warning.
- const AttributeList *Attr = DeclaratorInfo.getAttributes();
- while (Attr) {
- if (Attr->isKnownToGCC() && !Attr->isCXX11Attribute())
- Diag(Attr->getLoc(), diag::warn_gcc_attribute_location);
- Attr = Attr->getNext();
- }
+ for (const ParsedAttr &AL : DeclaratorInfo.getAttributes())
+ if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
+ Diag(AL.getLoc(), diag::warn_gcc_attribute_location);
+
MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo, VS);
}
}
@@ -2318,7 +2302,7 @@ bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
return false;
}
-/// \brief Look for declaration specifiers possibly occurring after C++11
+/// Look for declaration specifiers possibly occurring after C++11
/// virt-specifier-seq and diagnose them.
void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
Declarator &D,
@@ -2422,7 +2406,7 @@ void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
///
Parser::DeclGroupPtrTy
Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
- AttributeList *AccessAttrs,
+ ParsedAttributes &AccessAttrs,
const ParsedTemplateInfo &TemplateInfo,
ParsingDeclRAIIObject *TemplateDiags) {
if (Tok.is(tok::at)) {
@@ -2474,7 +2458,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
SourceLocation TemplateKWLoc;
UnqualifiedId Name;
if (ParseUnqualifiedId(SS, false, true, true, false, nullptr,
- TemplateKWLoc, Name)) {
+ &TemplateKWLoc, Name)) {
SkipUntil(tok::semi);
return nullptr;
}
@@ -2486,10 +2470,12 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
return nullptr;
}
+ // FIXME: We should do something with the 'template' keyword here.
return DeclGroupPtrTy::make(DeclGroupRef(Actions.ActOnUsingDeclaration(
getCurScope(), AS, /*UsingLoc*/ SourceLocation(),
/*TypenameLoc*/ SourceLocation(), SS, Name,
- /*EllipsisLoc*/ SourceLocation(), /*AttrList*/ nullptr)));
+ /*EllipsisLoc*/ SourceLocation(),
+ /*AttrList*/ ParsedAttributesView())));
}
}
@@ -2509,7 +2495,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
SourceLocation DeclEnd;
return DeclGroupPtrTy::make(
DeclGroupRef(ParseTemplateDeclarationOrSpecialization(
- Declarator::MemberContext, DeclEnd, AS, AccessAttrs)));
+ DeclaratorContext::MemberContext, DeclEnd, AccessAttrs, AS)));
}
// Handle: member-declaration ::= '__extension__' member-declaration
@@ -2522,12 +2508,12 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
}
ParsedAttributesWithRange attrs(AttrFactory);
- ParsedAttributesWithRange FnAttrs(AttrFactory);
+ ParsedAttributesViewWithRange FnAttrs;
// Optional C++11 attribute-specifier
MaybeParseCXX11Attributes(attrs);
// We need to keep these attributes for future diagnostic
// before they are taken over by declaration specifier.
- FnAttrs.addAll(attrs.getList());
+ FnAttrs.addAll(attrs.begin(), attrs.end());
FnAttrs.Range = attrs.Range;
MaybeParseMicrosoftAttributes(attrs);
@@ -2545,7 +2531,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
}
SourceLocation DeclEnd;
// Otherwise, it must be a using-declaration or an alias-declaration.
- return ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo,
+ return ParseUsingDeclaration(DeclaratorContext::MemberContext, TemplateInfo,
UsingLoc, DeclEnd, AS);
}
@@ -2559,7 +2545,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
if (MalformedTypeSpec)
DS.SetTypeSpecError();
- ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class,
+ ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class,
&CommonLateParsedAttrs);
// Turn off colon protection that was set for declspec.
@@ -2569,7 +2555,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// may get this far before the problem becomes obvious.
if (DS.hasTagDefinition() &&
TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate &&
- DiagnoseMissingSemiAfterTagDefinition(DS, AS, DSC_class,
+ DiagnoseMissingSemiAfterTagDefinition(DS, AS, DeclSpecContext::DSC_class,
&CommonLateParsedAttrs))
return nullptr;
@@ -2593,7 +2579,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
return Actions.ConvertDeclToDeclGroup(TheDecl);
}
- ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
+ ParsingDeclarator DeclaratorInfo(*this, DS, DeclaratorContext::MemberContext);
VirtSpecifiers VS;
// Hold late-parsed attributes so we can attach a Decl to them later.
@@ -2774,7 +2760,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// initialize it.
ThisDecl = VT->getTemplatedDecl();
- if (ThisDecl && AccessAttrs)
+ if (ThisDecl)
Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs);
}
@@ -2852,7 +2838,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
break;
if (Tok.isAtStartOfLine() &&
- !MightBeDeclarator(Declarator::MemberContext)) {
+ !MightBeDeclarator(DeclaratorContext::MemberContext)) {
// This comma was followed by a line-break and something which can't be
// the start of a declarator. The comma was probably a typo for a
// semicolon.
@@ -3006,10 +2992,12 @@ void Parser::SkipCXXMemberSpecification(SourceLocation RecordLoc,
Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
AccessSpecifier &AS, ParsedAttributesWithRange &AccessAttrs,
DeclSpec::TST TagType, Decl *TagDecl) {
+ ParenBraceBracketBalancer BalancerRAIIObj(*this);
+
switch (Tok.getKind()) {
case tok::kw___if_exists:
case tok::kw___if_not_exists:
- ParseMicrosoftIfExistsClassDeclaration(TagType, AS);
+ ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, AS);
return nullptr;
case tok::semi:
@@ -3075,8 +3063,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
Diag(ASLoc, diag::err_access_specifier_interface) << (AS == AS_protected);
}
- if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc,
- AccessAttrs.getList())) {
+ if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc, AccessAttrs)) {
// found another attribute than only annotations
AccessAttrs.clear();
}
@@ -3089,7 +3076,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
TagDecl);
default:
- return ParseCXXClassMemberDeclaration(AS, AccessAttrs.getList());
+ return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
}
}
@@ -3108,7 +3095,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
TagType == DeclSpec::TST_union ||
TagType == DeclSpec::TST_class) && "Invalid TagType!");
- PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
+ PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,
"parsing struct/union/class body");
// Determine whether this is a non-nested class. Note that local
@@ -3277,9 +3264,8 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
if (TagDecl)
Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
- T.getOpenLocation(),
- T.getCloseLocation(),
- attrs.getList());
+ T.getOpenLocation(),
+ T.getCloseLocation(), attrs);
// C++11 [class.mem]p2:
// Within the class member-specification, the class is regarded as complete
@@ -3502,7 +3488,7 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
return Diag(Tok, diag::err_expected) << tok::l_paren;
}
-/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]).
+/// Parse a C++ exception-specification if present (C++0x [except.spec]).
///
/// exception-specification:
/// dynamic-exception-specification
@@ -3583,15 +3569,11 @@ Parser::tryParseExceptionSpecification(bool Delayed,
// There is an argument.
BalancedDelimiterTracker T(*this, tok::l_paren);
T.consumeOpen();
- NoexceptType = EST_ComputedNoexcept;
NoexceptExpr = ParseConstantExpression();
T.consumeClose();
- // The argument must be contextually convertible to bool. We use
- // CheckBooleanCondition for this purpose.
- // FIXME: Add a proper Sema entry point for this.
if (!NoexceptExpr.isInvalid()) {
- NoexceptExpr =
- Actions.CheckBooleanCondition(KeywordLoc, NoexceptExpr.get());
+ NoexceptExpr = Actions.ActOnNoexceptSpec(KeywordLoc, NoexceptExpr.get(),
+ NoexceptType);
NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
} else {
NoexceptType = EST_BasicNoexcept;
@@ -3704,15 +3686,18 @@ ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
/// ParseTrailingReturnType - Parse a trailing return type on a new-style
/// function declaration.
-TypeResult Parser::ParseTrailingReturnType(SourceRange &Range) {
+TypeResult Parser::ParseTrailingReturnType(SourceRange &Range,
+ bool MayBeFollowedByDirectInit) {
assert(Tok.is(tok::arrow) && "expected arrow");
ConsumeToken();
- return ParseTypeName(&Range, Declarator::TrailingReturnContext);
+ return ParseTypeName(&Range, MayBeFollowedByDirectInit
+ ? DeclaratorContext::TrailingReturnVarContext
+ : DeclaratorContext::TrailingReturnContext);
}
-/// \brief We have just started parsing the definition of a new class,
+/// We have just started parsing the definition of a new class,
/// so push that class onto our stack of classes that is currently
/// being parsed.
Sema::ParsingClassState
@@ -3724,7 +3709,7 @@ Parser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass,
return Actions.PushParsingClass();
}
-/// \brief Deallocate the given parsed class and all of its nested
+/// Deallocate the given parsed class and all of its nested
/// classes.
void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
@@ -3732,7 +3717,7 @@ void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
delete Class;
}
-/// \brief Pop the top class of the stack of classes that are
+/// Pop the top class of the stack of classes that are
/// currently being parsed.
///
/// This routine should be called when we have finished parsing the
@@ -3770,7 +3755,7 @@ void Parser::PopParsingClass(Sema::ParsingClassState state) {
Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
}
-/// \brief Try to parse an 'identifier' which appears within an attribute-token.
+/// Try to parse an 'identifier' which appears within an attribute-token.
///
/// \return the parsed identifier on success, and 0 if the next token is not an
/// attribute-token.
@@ -3818,16 +3803,15 @@ IdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) {
static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
IdentifierInfo *ScopeName) {
- switch (AttributeList::getKind(AttrName, ScopeName,
- AttributeList::AS_CXX11)) {
- case AttributeList::AT_CarriesDependency:
- case AttributeList::AT_Deprecated:
- case AttributeList::AT_FallThrough:
- case AttributeList::AT_CXX11NoReturn:
+ switch (ParsedAttr::getKind(AttrName, ScopeName, ParsedAttr::AS_CXX11)) {
+ case ParsedAttr::AT_CarriesDependency:
+ case ParsedAttr::AT_Deprecated:
+ case ParsedAttr::AT_FallThrough:
+ case ParsedAttr::AT_CXX11NoReturn:
return true;
- case AttributeList::AT_WarnUnusedResult:
+ case ParsedAttr::AT_WarnUnusedResult:
return !ScopeName && AttrName->getName().equals("nodiscard");
- case AttributeList::AT_Unused:
+ case ParsedAttr::AT_Unused:
return !ScopeName && AttrName->getName().equals("maybe_unused");
default:
return false;
@@ -3857,8 +3841,8 @@ bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");
SourceLocation LParenLoc = Tok.getLocation();
const LangOptions &LO = getLangOpts();
- AttributeList::Syntax Syntax =
- LO.CPlusPlus ? AttributeList::AS_CXX11 : AttributeList::AS_C2x;
+ ParsedAttr::Syntax Syntax =
+ LO.CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x;
// If the attribute isn't known, we will not attempt to parse any
// arguments.
@@ -3889,25 +3873,26 @@ bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
- const AttributeList *Attr = Attrs.getList();
- if (Attr && IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
+ if (!Attrs.empty() &&
+ IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
+ ParsedAttr &Attr = *Attrs.begin();
// If the attribute is a standard or built-in attribute and we are
// parsing an argument list, we need to determine whether this attribute
// was allowed to have an argument list (such as [[deprecated]]), and how
// many arguments were parsed (so we can diagnose on [[deprecated()]]).
- if (Attr->getMaxArgs() && !NumArgs) {
+ if (Attr.getMaxArgs() && !NumArgs) {
// 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;
- Attr->setInvalid(true);
- } else if (!Attr->getMaxArgs()) {
+ Attr.setInvalid(true);
+ } 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
// presence of the argument list (even if empty) is diagnosed.
Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
<< AttrName
<< FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));
- Attr->setInvalid(true);
+ Attr.setInvalid(true);
}
}
return true;
@@ -4026,12 +4011,11 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
AttrName,
SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc),
ScopeName, ScopeLoc, nullptr, 0,
- getLangOpts().CPlusPlus ? AttributeList::AS_CXX11
- : AttributeList::AS_C2x);
+ getLangOpts().CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x);
if (TryConsumeToken(tok::ellipsis))
Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
- << AttrName->getName();
+ << AttrName;
}
if (ExpectAndConsume(tok::r_square))
@@ -4179,7 +4163,7 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
if (!T.consumeClose()) {
Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr,
SourceLocation(), ArgExprs.data(), ArgExprs.size(),
- AttributeList::AS_Microsoft);
+ ParsedAttr::AS_Microsoft);
}
}
@@ -4217,8 +4201,9 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
} while (Tok.is(tok::l_square));
}
-void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
- AccessSpecifier& CurAS) {
+void Parser::ParseMicrosoftIfExistsClassDeclaration(
+ DeclSpec::TST TagType, ParsedAttributes &AccessAttrs,
+ AccessSpecifier &CurAS) {
IfExistsCondition Result;
if (ParseMicrosoftIfExistsCondition(Result))
return;
@@ -4248,7 +4233,8 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
// __if_exists, __if_not_exists can nest.
if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
- ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
+ ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType,
+ AccessAttrs, CurAS);
continue;
}
@@ -4265,7 +4251,8 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
SourceLocation ASLoc = Tok.getLocation();
ConsumeToken();
if (Tok.is(tok::colon))
- Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
+ Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation(),
+ ParsedAttributesView{});
else
Diag(Tok, diag::err_expected) << tok::colon;
ConsumeToken();
@@ -4273,7 +4260,7 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
}
// Parse all the comma separated declarators.
- ParseCXXClassMemberDeclaration(CurAS, nullptr);
+ ParseCXXClassMemberDeclaration(CurAS, AccessAttrs);
}
Braces.consumeClose();
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index bc587628c954..4a0e1c5e3413 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Provides the Expression parsing implementation.
+/// Provides the Expression parsing implementation.
///
/// Expressions in C99 basically consist of a bunch of binary operators with
/// unary operators and other random stuff at the leaves.
@@ -32,7 +32,7 @@
#include "llvm/ADT/SmallVector.h"
using namespace clang;
-/// \brief Simple precedence-based parser for binary/ternary operators.
+/// Simple precedence-based parser for binary/ternary operators.
///
/// Note: we diverge from the C99 grammar when parsing the assignment-expression
/// production. C99 specifies that the LHS of an assignment operator should be
@@ -156,7 +156,7 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
return ParseRHSOfBinaryExpression(LHS, prec::Comma);
}
-/// \brief Parse an expr that doesn't include (top-level) commas.
+/// Parse an expr that doesn't include (top-level) commas.
ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
@@ -175,7 +175,7 @@ ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
}
-/// \brief Parse an assignment expression where part of an Objective-C message
+/// Parse an assignment expression where part of an Objective-C message
/// send has already been parsed.
///
/// In this case \p LBracLoc indicates the location of the '[' of the message
@@ -217,7 +217,15 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) {
return ParseConstantExpressionInExprEvalContext(isTypeCast);
}
-/// \brief Parse a constraint-expression.
+ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) {
+ EnterExpressionEvaluationContext ConstantEvaluated(
+ Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+ ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
+ ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
+ return Actions.ActOnCaseExpr(CaseLoc, Res);
+}
+
+/// Parse a constraint-expression.
///
/// \verbatim
/// constraint-expression: [Concepts TS temp.constr.decl p1]
@@ -246,30 +254,6 @@ bool Parser::isNotExpressionStart() {
return isKnownToBeDeclarationSpecifier();
}
-/// We've parsed something that could plausibly be intended to be a template
-/// name (\p LHS) followed by a '<' token, and the following code can't possibly
-/// be an expression. Determine if this is likely to be a template-id and if so,
-/// diagnose it.
-bool Parser::diagnoseUnknownTemplateId(ExprResult LHS, SourceLocation Less) {
- TentativeParsingAction TPA(*this);
- // FIXME: We could look at the token sequence in a lot more detail here.
- if (SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
- StopAtSemi | StopBeforeMatch)) {
- TPA.Commit();
-
- SourceLocation Greater;
- ParseGreaterThanInTemplateList(Greater, true, false);
- Actions.diagnoseExprIntendedAsTemplateName(getCurScope(), LHS,
- Less, Greater);
- return true;
- }
-
- // There's no matching '>' token, this probably isn't supposed to be
- // interpreted as a template-id. Parse it as an (ill-formed) comparison.
- TPA.Revert();
- return false;
-}
-
bool Parser::isFoldOperator(prec::Level Level) const {
return Level > prec::Unknown && Level != prec::Conditional &&
Level != prec::Spaceship;
@@ -279,7 +263,7 @@ bool Parser::isFoldOperator(tok::TokenKind Kind) const {
return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true));
}
-/// \brief Parse a binary expression that starts with \p LHS and has a
+/// Parse a binary expression that starts with \p LHS and has a
/// precedence of at least \p MinPrec.
ExprResult
Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
@@ -302,6 +286,14 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
if (OpToken.is(tok::caretcaret)) {
return ExprError(Diag(Tok, diag::err_opencl_logical_exclusive_or));
}
+
+ // If we're potentially in a template-id, we may now be able to determine
+ // whether we're actually in one or not.
+ if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater,
+ tok::greatergreatergreater) &&
+ checkPotentialAngleBracketDelimiter(OpToken))
+ return ExprError();
+
// Bail out when encountering a comma followed by a token which can't
// possibly be the start of an expression. For instance:
// int f() { return 1, }
@@ -313,16 +305,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
return LHS;
}
- // If a '<' token is followed by a type that can be a template argument and
- // cannot be an expression, then this is ill-formed, but might be intended
- // to be a template-id.
- if (OpToken.is(tok::less) && Actions.mightBeIntendedToBeTemplateName(LHS) &&
- (isKnownToBeDeclarationSpecifier() ||
- Tok.isOneOf(tok::greater, tok::greatergreater,
- tok::greatergreatergreater)) &&
- diagnoseUnknownTemplateId(LHS, OpToken.getLocation()))
- return ExprError();
-
// If the next token is an ellipsis, then this is a fold-expression. Leave
// it alone so we can handle it in the paren expression.
if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) {
@@ -336,7 +318,17 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
// Special case handling for the ternary operator.
ExprResult TernaryMiddle(true);
if (NextTokPrec == prec::Conditional) {
- if (Tok.isNot(tok::colon)) {
+ if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
+ // Parse a braced-init-list here for error recovery purposes.
+ SourceLocation BraceLoc = Tok.getLocation();
+ TernaryMiddle = ParseBraceInitializer();
+ if (!TernaryMiddle.isInvalid()) {
+ Diag(BraceLoc, diag::err_init_list_bin_op)
+ << /*RHS*/ 1 << PP.getSpelling(OpToken)
+ << Actions.getExprRange(TernaryMiddle.get());
+ TernaryMiddle = ExprError();
+ }
+ } else if (Tok.isNot(tok::colon)) {
// Don't parse FOO:BAR as if it were a typo for FOO::BAR.
ColonProtectionRAIIObject X(*this);
@@ -345,11 +337,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
// In particular, the RHS of the '?' is 'expression', not
// 'logical-OR-expression' as we might expect.
TernaryMiddle = ParseExpression();
- if (TernaryMiddle.isInvalid()) {
- Actions.CorrectDelayedTyposInExpr(LHS);
- LHS = ExprError();
- TernaryMiddle = nullptr;
- }
} else {
// Special case handling of "X ? Y : Z" where Y is empty:
// logical-OR-expression '?' ':' conditional-expression [GNU]
@@ -357,6 +344,12 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
Diag(Tok, diag::ext_gnu_conditional_expr);
}
+ if (TernaryMiddle.isInvalid()) {
+ Actions.CorrectDelayedTyposInExpr(LHS);
+ LHS = ExprError();
+ TernaryMiddle = nullptr;
+ }
+
if (!TryConsumeToken(tok::colon, ColonLoc)) {
// Otherwise, we're missing a ':'. Assume that this was a typo that
// the user forgot. If we're not in a macro expansion, we can suggest
@@ -469,6 +462,11 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
if (ThisPrec == prec::Assignment) {
Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists)
<< Actions.getExprRange(RHS.get());
+ } else if (ColonLoc.isValid()) {
+ Diag(ColonLoc, diag::err_init_list_bin_op)
+ << /*RHS*/1 << ":"
+ << Actions.getExprRange(RHS.get());
+ LHS = ExprError();
} else {
Diag(OpToken, diag::err_init_list_bin_op)
<< /*RHS*/1 << PP.getSpelling(OpToken)
@@ -513,7 +511,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
}
}
-/// \brief Parse a cast-expression, or, if \p isUnaryExpression is true,
+/// Parse a cast-expression, or, if \p isUnaryExpression is true,
/// parse a unary-expression.
///
/// \p isAddressOfOperand exists because an id-expression that is the
@@ -570,7 +568,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
};
}
-/// \brief Parse a cast-expression, or, if \pisUnaryExpression is true, parse
+/// Parse a cast-expression, or, if \pisUnaryExpression is true, parse
/// a unary-expression.
///
/// \p isAddressOfOperand exists because an id-expression that is the operand
@@ -619,6 +617,8 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
/// [GNU] '__FUNCTION__'
/// [MS] '__FUNCDNAME__'
/// [MS] 'L__FUNCTION__'
+/// [MS] '__FUNCSIG__'
+/// [MS] 'L__FUNCSIG__'
/// [GNU] '__PRETTY_FUNCTION__'
/// [GNU] '(' compound-statement ')'
/// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
@@ -820,6 +820,8 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
assert(Res.get() == nullptr && "Stray primary-expression annotation?");
Res = getExprAnnotation(Tok);
ConsumeAnnotationToken();
+ if (!Res.isInvalid() && Tok.is(tok::less))
+ checkPotentialAngleBracket(Res);
break;
case tok::kw___super:
@@ -1000,7 +1002,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ,
Actions.getASTContext().getPrintingPolicy());
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
TypeResult Ty = Actions.ActOnTypeName(getCurScope(),
DeclaratorInfo);
if (Ty.isInvalid())
@@ -1039,11 +1041,13 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
isAddressOfOperand, std::move(Validator),
/*IsInlineAsmIdentifier=*/false,
Tok.is(tok::r_paren) ? nullptr : &Replacement);
- if (!Res.isInvalid() && !Res.get()) {
+ if (!Res.isInvalid() && Res.isUnset()) {
UnconsumeToken(Replacement);
return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
NotCastExpr, isTypeCast);
}
+ if (!Res.isInvalid() && Tok.is(tok::less))
+ checkPotentialAngleBracket(Res);
break;
}
case tok::char_constant: // constant: character-constant
@@ -1059,6 +1063,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS]
case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS]
case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS]
+ case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS]
case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
ConsumeToken();
@@ -1209,7 +1214,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
PrevSpec, DiagID, Type,
Actions.getASTContext().getPrintingPolicy());
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
if (Ty.isInvalid())
break;
@@ -1224,6 +1229,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::annot_decltype:
case tok::kw_char:
case tok::kw_wchar_t:
+ case tok::kw_char8_t:
case tok::kw_char16_t:
case tok::kw_char32_t:
case tok::kw_bool:
@@ -1449,7 +1455,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
return Res;
}
-/// \brief Once the leading part of a postfix-expression is parsed, this
+/// Once the leading part of a postfix-expression is parsed, this
/// method parses any suffixes that apply.
///
/// \verbatim
@@ -1686,8 +1692,10 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
CXXScopeSpec SS;
ParsedType ObjectType;
bool MayBePseudoDestructor = false;
+ Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr;
+
if (getLangOpts().CPlusPlus && !LHS.isInvalid()) {
- Expr *Base = LHS.get();
+ Expr *Base = OrigLHS;
const Type* BaseType = Base->getType().getTypePtrOrNull();
if (BaseType && Tok.is(tok::l_paren) &&
(BaseType->isFunctionType() ||
@@ -1712,11 +1720,25 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
}
if (Tok.is(tok::code_completion)) {
+ tok::TokenKind CorrectedOpKind =
+ OpKind == tok::arrow ? tok::period : tok::arrow;
+ ExprResult CorrectedLHS(/*IsInvalid=*/true);
+ if (getLangOpts().CPlusPlus && OrigLHS) {
+ const bool DiagsAreSuppressed = Diags.getSuppressAllDiagnostics();
+ Diags.setSuppressAllDiagnostics(true);
+ CorrectedLHS = Actions.ActOnStartCXXMemberReference(
+ getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType,
+ MayBePseudoDestructor);
+ Diags.setSuppressAllDiagnostics(DiagsAreSuppressed);
+ }
+
+ Expr *Base = LHS.get();
+ Expr *CorrectedBase = CorrectedLHS.get();
+
// Code completion for a member access expression.
- if (Expr *Base = LHS.get())
- Actions.CodeCompleteMemberReferenceExpr(
- getCurScope(), Base, OpLoc, OpKind == tok::arrow,
- ExprStatementTokLoc == Base->getLocStart());
+ Actions.CodeCompleteMemberReferenceExpr(
+ getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow,
+ Base && ExprStatementTokLoc == Base->getLocStart());
cutOffParsing();
return ExprError();
@@ -1755,7 +1777,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
/*AllowConstructorName=*/
getLangOpts().MicrosoftExt,
/*AllowDeductionGuide=*/false,
- ObjectType, TemplateKWLoc, Name)) {
+ ObjectType, &TemplateKWLoc, Name)) {
(void)Actions.CorrectDelayedTyposInExpr(LHS);
LHS = ExprError();
}
@@ -1765,6 +1787,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
OpKind, SS, TemplateKWLoc, Name,
CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
: nullptr);
+ if (!LHS.isInvalid() && Tok.is(tok::less))
+ checkPotentialAngleBracket(LHS);
break;
}
case tok::plusplus: // postfix-expression: postfix-expression '++'
@@ -1824,7 +1848,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
if (isTypeIdUnambiguously()) {
DeclSpec DS(AttrFactory);
ParseSpecifierQualifierList(DS);
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
ParseDeclarator(DeclaratorInfo);
SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation());
@@ -1881,7 +1905,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
}
-/// \brief Parse a sizeof or alignof expression.
+/// Parse a sizeof or alignof expression.
///
/// \verbatim
/// unary-expression: [C99 6.5.3]
@@ -2381,7 +2405,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// Parse the type declarator.
DeclSpec DS(AttrFactory);
ParseSpecifierQualifierList(DS);
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
ParseDeclarator(DeclaratorInfo);
// If our type is followed by an identifier and either ':' or ']', then
@@ -2694,7 +2718,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
Types, Exprs);
}
-/// \brief Parse A C++1z fold-expression after the opening paren and optional
+/// Parse A C++1z fold-expression after the opening paren and optional
/// left-hand-side expression.
///
/// \verbatim
@@ -2802,7 +2826,10 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
if (Tok.isNot(tok::comma))
break;
// Move to the next argument, remember where the comma was.
+ Token Comma = Tok;
CommaLocs.push_back(ConsumeToken());
+
+ checkPotentialAngleBracketDelimiter(Comma);
}
if (SawError) {
// Ensure typos get diagnosed when errors were encountered while parsing the
@@ -2837,7 +2864,10 @@ Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs,
return false;
// Move to the next argument, remember where the comma was.
+ Token Comma = Tok;
CommaLocs.push_back(ConsumeToken());
+
+ checkPotentialAngleBracketDelimiter(Comma);
}
}
@@ -2858,7 +2888,7 @@ void Parser::ParseBlockId(SourceLocation CaretLoc) {
ParseSpecifierQualifierList(DS);
// Parse the block-declarator.
- Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::BlockLiteralContext);
DeclaratorInfo.setFunctionDefinitionKind(FDK_Definition);
ParseDeclarator(DeclaratorInfo);
@@ -2897,7 +2927,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
// Parse the return type if present.
DeclSpec DS(AttrFactory);
- Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
+ Declarator ParamInfo(DS, DeclaratorContext::BlockLiteralContext);
ParamInfo.setFunctionDefinitionKind(FDK_Definition);
// FIXME: Since the return type isn't actually parsed, it can't be used to
// fill ParamInfo with an initial valid range, so do it manually.
@@ -2929,33 +2959,31 @@ ExprResult Parser::ParseBlockLiteralExpression() {
ParseBlockId(CaretLoc);
} else {
// Otherwise, pretend we saw (void).
- ParsedAttributes attrs(AttrFactory);
SourceLocation NoLoc;
- ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/true,
- /*IsAmbiguous=*/false,
- /*RParenLoc=*/NoLoc,
- /*ArgInfo=*/nullptr,
- /*NumArgs=*/0,
- /*EllipsisLoc=*/NoLoc,
- /*RParenLoc=*/NoLoc,
- /*TypeQuals=*/0,
- /*RefQualifierIsLvalueRef=*/true,
- /*RefQualifierLoc=*/NoLoc,
- /*ConstQualifierLoc=*/NoLoc,
- /*VolatileQualifierLoc=*/NoLoc,
- /*RestrictQualifierLoc=*/NoLoc,
- /*MutableLoc=*/NoLoc,
- EST_None,
- /*ESpecRange=*/SourceRange(),
- /*Exceptions=*/nullptr,
- /*ExceptionRanges=*/nullptr,
- /*NumExceptions=*/0,
- /*NoexceptExpr=*/nullptr,
- /*ExceptionSpecTokens=*/nullptr,
- /*DeclsInPrototype=*/None,
- CaretLoc, CaretLoc,
- ParamInfo),
- attrs, CaretLoc);
+ ParamInfo.AddTypeInfo(
+ DeclaratorChunk::getFunction(/*HasProto=*/true,
+ /*IsAmbiguous=*/false,
+ /*RParenLoc=*/NoLoc,
+ /*ArgInfo=*/nullptr,
+ /*NumArgs=*/0,
+ /*EllipsisLoc=*/NoLoc,
+ /*RParenLoc=*/NoLoc,
+ /*TypeQuals=*/0,
+ /*RefQualifierIsLvalueRef=*/true,
+ /*RefQualifierLoc=*/NoLoc,
+ /*ConstQualifierLoc=*/NoLoc,
+ /*VolatileQualifierLoc=*/NoLoc,
+ /*RestrictQualifierLoc=*/NoLoc,
+ /*MutableLoc=*/NoLoc, EST_None,
+ /*ESpecRange=*/SourceRange(),
+ /*Exceptions=*/nullptr,
+ /*ExceptionRanges=*/nullptr,
+ /*NumExceptions=*/0,
+ /*NoexceptExpr=*/nullptr,
+ /*ExceptionSpecTokens=*/nullptr,
+ /*DeclsInPrototype=*/None, CaretLoc,
+ CaretLoc, ParamInfo),
+ CaretLoc);
MaybeParseGNUAttributes(ParamInfo);
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 959cb7a61d3a..26e75999518a 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -100,7 +100,7 @@ void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,
/*AtDigraph*/false);
}
-/// \brief Parse global scope or nested-name-specifier if present.
+/// Parse global scope or nested-name-specifier if present.
///
/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
/// may be preceded by '::'). Note that this routine will not parse ::new or
@@ -292,8 +292,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
break;
}
- if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId &&
- TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) {
+ if (TemplateName.getKind() != UnqualifiedIdKind::IK_OperatorFunctionId &&
+ TemplateName.getKind() != UnqualifiedIdKind::IK_LiteralOperatorId) {
Diag(TemplateName.getSourceRange().getBegin(),
diag::err_id_after_template_in_nested_name_spec)
<< TemplateName.getSourceRange();
@@ -515,7 +515,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
<< FixItHint::CreateInsertion(Tok.getLocation(), "template ");
if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName(
- getCurScope(), SS, SourceLocation(), TemplateName, ObjectType,
+ getCurScope(), SS, Tok.getLocation(), TemplateName, ObjectType,
EnteringContext, Template, /*AllowInjectedClassName*/ true)) {
// Consume the identifier.
ConsumeToken();
@@ -553,7 +553,7 @@ ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOpe
/*AllowDestructorName=*/false,
/*AllowConstructorName=*/false,
/*AllowDeductionGuide=*/false,
- /*ObjectType=*/nullptr, TemplateKWLoc, Name))
+ /*ObjectType=*/nullptr, &TemplateKWLoc, Name))
return ExprError();
// This is only the direct operand of an & operator if it is not
@@ -561,10 +561,13 @@ ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOpe
if (isAddressOfOperand && isPostfixExpressionSuffixStart())
isAddressOfOperand = false;
- return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name,
- Tok.is(tok::l_paren), isAddressOfOperand,
- nullptr, /*IsInlineAsmIdentifier=*/false,
- &Replacement);
+ ExprResult E = Actions.ActOnIdExpression(
+ getCurScope(), SS, TemplateKWLoc, Name, Tok.is(tok::l_paren),
+ isAddressOfOperand, nullptr, /*IsInlineAsmIdentifier=*/false,
+ &Replacement);
+ if (!E.isInvalid() && !E.isUnset() && Tok.is(tok::less))
+ checkPotentialAngleBracket(E);
+ return E;
}
/// ParseCXXIdExpression - Handle id-expression.
@@ -730,7 +733,7 @@ ExprResult Parser::TryParseLambdaExpression() {
return ParseLambdaExpressionAfterIntroducer(Intro);
}
-/// \brief Parse a lambda introducer.
+/// Parse a lambda introducer.
/// \param Intro A LambdaIntroducer filled in with information about the
/// contents of the lambda-introducer.
/// \param SkippedInits If non-null, we are disambiguating between an Obj-C
@@ -805,6 +808,7 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
IdentifierInfo *Id = nullptr;
SourceLocation EllipsisLoc;
ExprResult Init;
+ SourceLocation LocStart = Tok.getLocation();
if (Tok.is(tok::star)) {
Loc = ConsumeToken();
@@ -978,8 +982,11 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
Loc, Kind == LCK_ByRef, Id, InitKind, InitExpr);
Init = InitExpr;
}
+
+ SourceLocation LocEnd = PrevTokLocation;
+
Intro.addCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init,
- InitCaptureType);
+ InitCaptureType, SourceRange(LocStart, LocEnd));
}
T.consumeClose();
@@ -1090,7 +1097,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// Parse lambda-declarator[opt].
DeclSpec DS(AttrFactory);
- Declarator D(DS, Declarator::LambdaExprContext);
+ Declarator D(DS, DeclaratorContext::LambdaExprContext);
TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
Actions.PushLambdaScope();
@@ -1106,12 +1113,12 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// after '(...)'. nvcc doesn't accept this.
auto WarnIfHasCUDATargetAttr = [&] {
if (getLangOpts().CUDA)
- for (auto *A = Attr.getList(); A != nullptr; A = A->getNext())
- if (A->getKind() == AttributeList::AT_CUDADevice ||
- A->getKind() == AttributeList::AT_CUDAHost ||
- A->getKind() == AttributeList::AT_CUDAGlobal)
- Diag(A->getLoc(), diag::warn_cuda_attr_lambda_position)
- << A->getName()->getName();
+ for (const ParsedAttr &A : Attr)
+ if (A.getKind() == ParsedAttr::AT_CUDADevice ||
+ A.getKind() == ParsedAttr::AT_CUDAHost ||
+ A.getKind() == ParsedAttr::AT_CUDAGlobal)
+ Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position)
+ << A.getName()->getName();
};
TypeResult TrailingReturnType;
@@ -1183,7 +1190,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
if (Tok.is(tok::arrow)) {
FunLocalRangeEnd = Tok.getLocation();
SourceRange Range;
- TrailingReturnType = ParseTrailingReturnType(Range);
+ TrailingReturnType =
+ ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false);
if (Range.getEnd().isValid())
DeclEndLoc = Range.getEnd();
}
@@ -1193,29 +1201,23 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
WarnIfHasCUDATargetAttr();
SourceLocation NoLoc;
- D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
- /*isAmbiguous=*/false,
- LParenLoc,
- ParamInfo.data(), ParamInfo.size(),
- EllipsisLoc, RParenLoc,
- DS.getTypeQualifiers(),
- /*RefQualifierIsLValueRef=*/true,
- /*RefQualifierLoc=*/NoLoc,
- /*ConstQualifierLoc=*/NoLoc,
- /*VolatileQualifierLoc=*/NoLoc,
- /*RestrictQualifierLoc=*/NoLoc,
- MutableLoc,
- ESpecType, ESpecRange,
- DynamicExceptions.data(),
- DynamicExceptionRanges.data(),
- DynamicExceptions.size(),
- NoexceptExpr.isUsable() ?
- NoexceptExpr.get() : nullptr,
- /*ExceptionSpecTokens*/nullptr,
- /*DeclsInPrototype=*/None,
- LParenLoc, FunLocalRangeEnd, D,
- TrailingReturnType),
- Attr, DeclEndLoc);
+ D.AddTypeInfo(DeclaratorChunk::getFunction(
+ /*hasProto=*/true,
+ /*isAmbiguous=*/false, LParenLoc, ParamInfo.data(),
+ ParamInfo.size(), EllipsisLoc, RParenLoc,
+ DS.getTypeQualifiers(),
+ /*RefQualifierIsLValueRef=*/true,
+ /*RefQualifierLoc=*/NoLoc,
+ /*ConstQualifierLoc=*/NoLoc,
+ /*VolatileQualifierLoc=*/NoLoc,
+ /*RestrictQualifierLoc=*/NoLoc, MutableLoc, ESpecType,
+ ESpecRange, DynamicExceptions.data(),
+ DynamicExceptionRanges.data(), DynamicExceptions.size(),
+ NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,
+ /*ExceptionSpecTokens*/ nullptr,
+ /*DeclsInPrototype=*/None, LParenLoc, FunLocalRangeEnd, D,
+ TrailingReturnType),
+ std::move(Attr), DeclEndLoc);
} else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute,
tok::kw_constexpr) ||
(Tok.is(tok::l_square) && NextToken().is(tok::l_square))) {
@@ -1253,7 +1255,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// Parse the return type, if there is one.
if (Tok.is(tok::arrow)) {
SourceRange Range;
- TrailingReturnType = ParseTrailingReturnType(Range);
+ TrailingReturnType =
+ ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false);
if (Range.getEnd().isValid())
DeclEndLoc = Range.getEnd();
}
@@ -1261,31 +1264,29 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
WarnIfHasCUDATargetAttr();
SourceLocation NoLoc;
- D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
- /*isAmbiguous=*/false,
- /*LParenLoc=*/NoLoc,
- /*Params=*/nullptr,
- /*NumParams=*/0,
- /*EllipsisLoc=*/NoLoc,
- /*RParenLoc=*/NoLoc,
- /*TypeQuals=*/0,
- /*RefQualifierIsLValueRef=*/true,
- /*RefQualifierLoc=*/NoLoc,
- /*ConstQualifierLoc=*/NoLoc,
- /*VolatileQualifierLoc=*/NoLoc,
- /*RestrictQualifierLoc=*/NoLoc,
- MutableLoc,
- EST_None,
- /*ESpecRange=*/SourceRange(),
- /*Exceptions=*/nullptr,
- /*ExceptionRanges=*/nullptr,
- /*NumExceptions=*/0,
- /*NoexceptExpr=*/nullptr,
- /*ExceptionSpecTokens=*/nullptr,
- /*DeclsInPrototype=*/None,
- DeclLoc, DeclEndLoc, D,
- TrailingReturnType),
- Attr, DeclEndLoc);
+ D.AddTypeInfo(DeclaratorChunk::getFunction(
+ /*hasProto=*/true,
+ /*isAmbiguous=*/false,
+ /*LParenLoc=*/NoLoc,
+ /*Params=*/nullptr,
+ /*NumParams=*/0,
+ /*EllipsisLoc=*/NoLoc,
+ /*RParenLoc=*/NoLoc,
+ /*TypeQuals=*/0,
+ /*RefQualifierIsLValueRef=*/true,
+ /*RefQualifierLoc=*/NoLoc,
+ /*ConstQualifierLoc=*/NoLoc,
+ /*VolatileQualifierLoc=*/NoLoc,
+ /*RestrictQualifierLoc=*/NoLoc, MutableLoc, EST_None,
+ /*ESpecRange=*/SourceRange(),
+ /*Exceptions=*/nullptr,
+ /*ExceptionRanges=*/nullptr,
+ /*NumExceptions=*/0,
+ /*NoexceptExpr=*/nullptr,
+ /*ExceptionSpecTokens=*/nullptr,
+ /*DeclsInPrototype=*/None, DeclLoc, DeclEndLoc, D,
+ TrailingReturnType),
+ std::move(Attr), DeclEndLoc);
}
// FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
@@ -1353,7 +1354,7 @@ ExprResult Parser::ParseCXXCasts() {
ParseSpecifierQualifierList(DS);
// Parse the abstract-declarator, if present.
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
ParseDeclarator(DeclaratorInfo);
SourceLocation RAngleBracketLoc = Tok.getLocation();
@@ -1498,7 +1499,7 @@ ExprResult Parser::ParseCXXUuidof() {
return Result;
}
-/// \brief Parse a C++ pseudo-destructor expression after the base,
+/// Parse a C++ pseudo-destructor expression after the base,
/// . or -> operator, and nested-name-specifier have already been
/// parsed.
///
@@ -1619,7 +1620,7 @@ ExprResult Parser::ParseThrowExpression() {
}
}
-/// \brief Parse the C++ Coroutines co_yield expression.
+/// Parse the C++ Coroutines co_yield expression.
///
/// co_yield-expression:
/// 'co_yield' assignment-expression[opt]
@@ -1660,7 +1661,7 @@ ExprResult Parser::ParseCXXThis() {
/// In C++1z onwards, the type specifier can also be a template-name.
ExprResult
Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
- Declarator DeclaratorInfo(DS, Declarator::FunctionalCastContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::FunctionalCastContext);
ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
assert((Tok.is(tok::l_paren) ||
@@ -1672,9 +1673,9 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
if (Init.isInvalid())
return Init;
Expr *InitList = Init.get();
- return Actions.ActOnCXXTypeConstructExpr(TypeRep, SourceLocation(),
- MultiExprArg(&InitList, 1),
- SourceLocation());
+ return Actions.ActOnCXXTypeConstructExpr(
+ TypeRep, InitList->getLocStart(), MultiExprArg(&InitList, 1),
+ InitList->getLocEnd(), /*ListInitialization=*/true);
} else {
BalancedDelimiterTracker T(*this, tok::l_paren);
T.consumeOpen();
@@ -1702,9 +1703,9 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
"Unexpected number of commas!");
- return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(),
- Exprs,
- T.getCloseLocation());
+ return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(),
+ Exprs, T.getCloseLocation(),
+ /*ListInitialization=*/false);
}
}
@@ -1733,6 +1734,8 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
SourceLocation Loc,
Sema::ConditionKind CK) {
+ ParenBraceBracketBalancer BalancerRAIIObj(*this);
+
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
cutOffParsing();
@@ -1742,17 +1745,34 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX11Attributes(attrs);
+ const auto WarnOnInit = [this, &CK] {
+ Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
+ ? diag::warn_cxx14_compat_init_statement
+ : diag::ext_init_statement)
+ << (CK == Sema::ConditionKind::Switch);
+ };
+
// Determine what kind of thing we have.
switch (isCXXConditionDeclarationOrInitStatement(InitStmt)) {
case ConditionOrInitStatement::Expression: {
ProhibitAttributes(attrs);
+ // We can have an empty expression here.
+ // if (; true);
+ if (InitStmt && Tok.is(tok::semi)) {
+ WarnOnInit();
+ SourceLocation SemiLoc = ConsumeToken();
+ *InitStmt = Actions.ActOnNullStmt(SemiLoc);
+ return ParseCXXCondition(nullptr, Loc, CK);
+ }
+
// Parse the expression.
ExprResult Expr = ParseExpression(); // expression
if (Expr.isInvalid())
return Sema::ConditionError();
if (InitStmt && Tok.is(tok::semi)) {
+ WarnOnInit();
*InitStmt = Actions.ActOnExprStmt(Expr.get());
ConsumeToken();
return ParseCXXCondition(nullptr, Loc, CK);
@@ -1762,13 +1782,11 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
}
case ConditionOrInitStatement::InitStmtDecl: {
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
- ? diag::warn_cxx14_compat_init_statement
- : diag::ext_init_statement)
- << (CK == Sema::ConditionKind::Switch);
+ WarnOnInit();
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
- DeclGroupPtrTy DG = ParseSimpleDeclaration(
- Declarator::InitStmtContext, DeclEnd, attrs, /*RequireSemi=*/true);
+ DeclGroupPtrTy DG =
+ ParseSimpleDeclaration(DeclaratorContext::InitStmtContext, DeclEnd,
+ attrs, /*RequireSemi=*/true);
*InitStmt = Actions.ActOnDeclStmt(DG, DeclStart, DeclEnd);
return ParseCXXCondition(nullptr, Loc, CK);
}
@@ -1781,10 +1799,10 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
// type-specifier-seq
DeclSpec DS(AttrFactory);
DS.takeAttributesFrom(attrs);
- ParseSpecifierQualifierList(DS, AS_none, DSC_condition);
+ ParseSpecifierQualifierList(DS, AS_none, DeclSpecContext::DSC_condition);
// declarator
- Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::ConditionContext);
ParseDeclarator(DeclaratorInfo);
// simple-asm-expr[opt]
@@ -1945,6 +1963,9 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
case tok::kw_wchar_t:
DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy);
break;
+ case tok::kw_char8_t:
+ DS.SetTypeSpecType(DeclSpec::TST_char8, Loc, PrevSpec, DiagID, Policy);
+ break;
case tok::kw_char16_t:
DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID, Policy);
break;
@@ -1982,12 +2003,12 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
/// type-specifier type-specifier-seq[opt]
///
bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
- ParseSpecifierQualifierList(DS, AS_none, DSC_type_specifier);
+ ParseSpecifierQualifierList(DS, AS_none, DeclSpecContext::DSC_type_specifier);
DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());
return false;
}
-/// \brief Finish parsing a C++ unqualified-id that is a template-id of
+/// Finish parsing a C++ unqualified-id that is a template-id of
/// some form.
///
/// This routine is invoked when a '<' is encountered after an identifier or
@@ -2027,15 +2048,14 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
ParsedType ObjectType,
UnqualifiedId &Id,
bool AssumeTemplateId) {
- assert((AssumeTemplateId || Tok.is(tok::less)) &&
- "Expected '<' to finish parsing a template-id");
-
+ assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");
+
TemplateTy Template;
TemplateNameKind TNK = TNK_Non_template;
switch (Id.getKind()) {
- case UnqualifiedId::IK_Identifier:
- case UnqualifiedId::IK_OperatorFunctionId:
- case UnqualifiedId::IK_LiteralOperatorId:
+ case UnqualifiedIdKind::IK_Identifier:
+ case UnqualifiedIdKind::IK_OperatorFunctionId:
+ case UnqualifiedIdKind::IK_LiteralOperatorId:
if (AssumeTemplateId) {
// We defer the injected-class-name checks until we've found whether
// this template-id is used to form a nested-name-specifier or not.
@@ -2058,11 +2078,11 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
// parse correctly as a template, so suggest the keyword 'template'
// before 'getAs' and treat this as a dependent template name.
std::string Name;
- if (Id.getKind() == UnqualifiedId::IK_Identifier)
+ if (Id.getKind() == UnqualifiedIdKind::IK_Identifier)
Name = Id.Identifier->getName();
else {
Name = "operator ";
- if (Id.getKind() == UnqualifiedId::IK_OperatorFunctionId)
+ if (Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId)
Name += getOperatorSpelling(Id.OperatorFunctionId.Operator);
else
Name += Id.Identifier->getName();
@@ -2079,7 +2099,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
}
break;
- case UnqualifiedId::IK_ConstructorName: {
+ case UnqualifiedIdKind::IK_ConstructorName: {
UnqualifiedId TemplateName;
bool MemberOfUnknownSpecialization;
TemplateName.setIdentifier(Name, NameLoc);
@@ -2090,7 +2110,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
break;
}
- case UnqualifiedId::IK_DestructorName: {
+ case UnqualifiedIdKind::IK_DestructorName: {
UnqualifiedId TemplateName;
bool MemberOfUnknownSpecialization;
TemplateName.setIdentifier(Name, NameLoc);
@@ -2125,22 +2145,24 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
// Parse the enclosed template argument list.
SourceLocation LAngleLoc, RAngleLoc;
TemplateArgList TemplateArgs;
- if (Tok.is(tok::less) && ParseTemplateIdAfterTemplateName(
- true, LAngleLoc, TemplateArgs, RAngleLoc))
+ if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs,
+ RAngleLoc))
return true;
-
- if (Id.getKind() == UnqualifiedId::IK_Identifier ||
- Id.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
- Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) {
+
+ if (Id.getKind() == UnqualifiedIdKind::IK_Identifier ||
+ Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId ||
+ Id.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) {
// Form a parsed representation of the template-id to be stored in the
// UnqualifiedId.
// FIXME: Store name for literal operator too.
IdentifierInfo *TemplateII =
- Id.getKind() == UnqualifiedId::IK_Identifier ? Id.Identifier : nullptr;
- OverloadedOperatorKind OpKind = Id.getKind() == UnqualifiedId::IK_Identifier
- ? OO_None
- : Id.OperatorFunctionId.Operator;
+ Id.getKind() == UnqualifiedIdKind::IK_Identifier ? Id.Identifier
+ : nullptr;
+ OverloadedOperatorKind OpKind =
+ Id.getKind() == UnqualifiedIdKind::IK_Identifier
+ ? OO_None
+ : Id.OperatorFunctionId.Operator;
TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
SS, TemplateKWLoc, Id.StartLocation, TemplateII, OpKind, Template, TNK,
@@ -2162,7 +2184,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
if (Type.isInvalid())
return true;
- if (Id.getKind() == UnqualifiedId::IK_ConstructorName)
+ if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName)
Id.setConstructorName(Type.get(), NameLoc, RAngleLoc);
else
Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc);
@@ -2170,7 +2192,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
return false;
}
-/// \brief Parse an operator-function-id or conversion-function-id as part
+/// Parse an operator-function-id or conversion-function-id as part
/// of a C++ unqualified-id.
///
/// This routine is responsible only for parsing the operator-function-id or
@@ -2395,7 +2417,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
// Parse the conversion-declarator, which is merely a sequence of
// ptr-operators.
- Declarator D(DS, Declarator::ConversionIdContext);
+ Declarator D(DS, DeclaratorContext::ConversionIdContext);
ParseDeclaratorInternal(D, /*DirectDeclParser=*/nullptr);
// Finish up the type.
@@ -2409,7 +2431,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
return false;
}
-/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the
+/// Parse a C++ unqualified-id (or a C identifier), which describes the
/// name of an entity.
///
/// \code
@@ -2446,16 +2468,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
bool AllowConstructorName,
bool AllowDeductionGuide,
ParsedType ObjectType,
- SourceLocation& TemplateKWLoc,
+ SourceLocation *TemplateKWLoc,
UnqualifiedId &Result) {
+ if (TemplateKWLoc)
+ *TemplateKWLoc = SourceLocation();
// Handle 'A::template B'. This is for template-ids which have not
// already been annotated by ParseOptionalCXXScopeSpecifier().
bool TemplateSpecified = false;
- if (getLangOpts().CPlusPlus && Tok.is(tok::kw_template) &&
- (ObjectType || SS.isSet())) {
- TemplateSpecified = true;
- TemplateKWLoc = ConsumeToken();
+ if (Tok.is(tok::kw_template)) {
+ if (TemplateKWLoc && (ObjectType || SS.isSet())) {
+ TemplateSpecified = true;
+ *TemplateKWLoc = ConsumeToken();
+ } else {
+ SourceLocation TemplateLoc = ConsumeToken();
+ Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id)
+ << FixItHint::CreateRemoval(TemplateLoc);
+ }
}
// unqualified-id:
@@ -2477,10 +2506,10 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
if (AllowConstructorName &&
Actions.isCurrentClassName(*Id, getCurScope(), &SS)) {
// We have parsed a constructor name.
- ParsedType Ty = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, false,
- false, nullptr,
- /*IsCtorOrDtorName=*/true,
- /*NonTrivialTypeSourceInfo=*/true);
+ ParsedType Ty = Actions.getConstructorName(*Id, IdLoc, getCurScope(), SS,
+ EnteringContext);
+ if (!Ty)
+ return true;
Result.setConstructorName(Ty, IdLoc, IdLoc);
} else if (getLangOpts().CPlusPlus17 &&
AllowDeductionGuide && SS.isEmpty() &&
@@ -2494,11 +2523,18 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
}
// If the next token is a '<', we may have a template.
- if (TemplateSpecified || Tok.is(tok::less))
- return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, Id, IdLoc,
- EnteringContext, ObjectType,
- Result, TemplateSpecified);
-
+ TemplateTy Template;
+ if (Tok.is(tok::less))
+ return ParseUnqualifiedIdTemplateId(
+ SS, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
+ EnteringContext, ObjectType, Result, TemplateSpecified);
+ else if (TemplateSpecified &&
+ Actions.ActOnDependentTemplateName(
+ getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
+ EnteringContext, Template,
+ /*AllowInjectedClassName*/ true) == TNK_Non_template)
+ return true;
+
return false;
}
@@ -2520,11 +2556,11 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
<< TemplateId->Name
<< FixItHint::CreateRemoval(
SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc));
- ParsedType Ty =
- Actions.getTypeName(*TemplateId->Name, TemplateId->TemplateNameLoc,
- getCurScope(), &SS, false, false, nullptr,
- /*IsCtorOrDtorName=*/true,
- /*NontrivialTypeSourceInfo=*/true);
+ ParsedType Ty = Actions.getConstructorName(
+ *TemplateId->Name, TemplateId->TemplateNameLoc, getCurScope(), SS,
+ EnteringContext);
+ if (!Ty)
+ return true;
Result.setConstructorName(Ty, TemplateId->TemplateNameLoc,
TemplateId->RAngleLoc);
ConsumeAnnotationToken();
@@ -2539,7 +2575,14 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
// We have already parsed a template-id; consume the annotation token as
// our unqualified-id.
Result.setTemplateId(TemplateId);
- TemplateKWLoc = TemplateId->TemplateKWLoc;
+ SourceLocation TemplateLoc = TemplateId->TemplateKWLoc;
+ if (TemplateLoc.isValid()) {
+ if (TemplateKWLoc && (ObjectType || SS.isSet()))
+ *TemplateKWLoc = TemplateLoc;
+ else
+ Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id)
+ << FixItHint::CreateRemoval(TemplateLoc);
+ }
ConsumeAnnotationToken();
return false;
}
@@ -2556,13 +2599,20 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
//
// template-id:
// operator-function-id < template-argument-list[opt] >
- if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
- Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) &&
- (TemplateSpecified || Tok.is(tok::less)))
- return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc,
- nullptr, SourceLocation(),
- EnteringContext, ObjectType,
- Result, TemplateSpecified);
+ TemplateTy Template;
+ if ((Result.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId ||
+ Result.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) &&
+ Tok.is(tok::less))
+ return ParseUnqualifiedIdTemplateId(
+ SS, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), nullptr,
+ SourceLocation(), EnteringContext, ObjectType, Result,
+ TemplateSpecified);
+ else if (TemplateSpecified &&
+ Actions.ActOnDependentTemplateName(
+ getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
+ EnteringContext, Template,
+ /*AllowInjectedClassName*/ true) == TNK_Non_template)
+ return true;
return false;
}
@@ -2630,12 +2680,11 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
IdentifierInfo *ClassName = Tok.getIdentifierInfo();
SourceLocation ClassNameLoc = ConsumeToken();
- if (TemplateSpecified || Tok.is(tok::less)) {
+ if (Tok.is(tok::less)) {
Result.setDestructorName(TildeLoc, nullptr, ClassNameLoc);
- return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc,
- ClassName, ClassNameLoc,
- EnteringContext, ObjectType,
- Result, TemplateSpecified);
+ return ParseUnqualifiedIdTemplateId(
+ SS, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), ClassName,
+ ClassNameLoc, EnteringContext, ObjectType, Result, TemplateSpecified);
}
// Note that this is a destructor name.
@@ -2696,7 +2745,7 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
SourceRange TypeIdParens;
DeclSpec DS(AttrFactory);
- Declarator DeclaratorInfo(DS, Declarator::CXXNewContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::CXXNewContext);
if (Tok.is(tok::l_paren)) {
// If it turns out to be a placement, we change the type location.
BalancedDelimiterTracker T(*this, tok::l_paren);
@@ -2836,10 +2885,9 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {
D.AddTypeInfo(DeclaratorChunk::getArray(0,
/*static=*/false, /*star=*/false,
- Size.get(),
- T.getOpenLocation(),
+ Size.get(), T.getOpenLocation(),
T.getCloseLocation()),
- Attrs, T.getCloseLocation());
+ std::move(Attrs), T.getCloseLocation());
if (T.getCloseLocation().isInvalid())
return;
@@ -2954,7 +3002,7 @@ static unsigned TypeTraitArity(tok::TokenKind kind) {
}
}
-/// \brief Parse the built-in type-trait pseudo-functions that allow
+/// Parse the built-in type-trait pseudo-functions that allow
/// implementation of the TR1/C++11 type traits templates.
///
/// primary-expression:
@@ -3172,7 +3220,7 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
if (ParseAs >= CompoundLiteral) {
// Parse the type declarator.
DeclSpec DS(AttrFactory);
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
{
ColonProtectionRAIIObject InnerColonProtection(*this);
ParseSpecifierQualifierList(DS);
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index fb8624a324b9..5c5b3cdfcf33 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -13,11 +13,11 @@
#include "clang/Parse/Parser.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/DeclSpec.h"
-#include "clang/Sema/PrettyDeclStackTrace.h"
#include "clang/Sema/Scope.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -45,7 +45,8 @@ void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) {
/// [OBJC] objc-protocol-definition
/// [OBJC] objc-method-definition
/// [OBJC] '@' 'end'
-Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() {
+Parser::DeclGroupPtrTy
+Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) {
SourceLocation AtLoc = ConsumeToken(); // the "@"
if (Tok.is(tok::code_completion)) {
@@ -58,15 +59,11 @@ Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() {
switch (Tok.getObjCKeywordID()) {
case tok::objc_class:
return ParseObjCAtClassDeclaration(AtLoc);
- case tok::objc_interface: {
- ParsedAttributes attrs(AttrFactory);
- SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
+ case tok::objc_interface:
+ SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, Attrs);
break;
- }
- case tok::objc_protocol: {
- ParsedAttributes attrs(AttrFactory);
- return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
- }
+ case tok::objc_protocol:
+ return ParseObjCAtProtocolDeclaration(AtLoc, Attrs);
case tok::objc_implementation:
return ParseObjCAtImplementationDeclaration(AtLoc);
case tok::objc_end:
@@ -290,7 +287,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
Decl *CategoryType = Actions.ActOnStartCategoryInterface(
AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
- EndProtoLoc, attrs.getList());
+ EndProtoLoc, attrs);
if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
@@ -356,17 +353,12 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
if (Tok.isNot(tok::less))
Actions.ActOnTypedefedProtocols(protocols, protocolLocs,
superClassId, superClassLoc);
-
- Decl *ClsType =
- Actions.ActOnStartClassInterface(getCurScope(), AtLoc, nameId, nameLoc,
- typeParameterList, superClassId,
- superClassLoc,
- typeArgs,
- SourceRange(typeArgsLAngleLoc,
- typeArgsRAngleLoc),
- protocols.data(), protocols.size(),
- protocolLocs.data(),
- EndProtoLoc, attrs.getList());
+
+ Decl *ClsType = Actions.ActOnStartClassInterface(
+ getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId,
+ superClassLoc, typeArgs,
+ SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(),
+ protocols.size(), protocolLocs.data(), EndProtoLoc, attrs);
if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
@@ -384,25 +376,21 @@ static void addContextSensitiveTypeNullability(Parser &P,
SourceLocation nullabilityLoc,
bool &addedToDeclSpec) {
// Create the attribute.
- auto getNullabilityAttr = [&]() -> AttributeList * {
- return D.getAttributePool().create(
- P.getNullabilityKeyword(nullability),
- SourceRange(nullabilityLoc),
- nullptr, SourceLocation(),
- nullptr, 0,
- AttributeList::AS_ContextSensitiveKeyword);
+ auto getNullabilityAttr = [&](AttributePool &Pool) -> ParsedAttr * {
+ return Pool.create(P.getNullabilityKeyword(nullability),
+ SourceRange(nullabilityLoc), nullptr, SourceLocation(),
+ nullptr, 0, ParsedAttr::AS_ContextSensitiveKeyword);
};
if (D.getNumTypeObjects() > 0) {
// Add the attribute to the declarator chunk nearest the declarator.
- auto nullabilityAttr = getNullabilityAttr();
- DeclaratorChunk &chunk = D.getTypeObject(0);
- nullabilityAttr->setNext(chunk.getAttrListRef());
- chunk.getAttrListRef() = nullabilityAttr;
+ D.getTypeObject(0).getAttrs().addAtStart(
+ getNullabilityAttr(D.getAttributePool()));
} else if (!addedToDeclSpec) {
// Otherwise, just put it on the declaration specifiers (if one
// isn't there already).
- D.getMutableDeclSpec().addAttributes(getNullabilityAttr());
+ D.getMutableDeclSpec().getAttributes().addAtStart(
+ getNullabilityAttr(D.getMutableDeclSpec().getAttributes().getPool()));
addedToDeclSpec = true;
}
}
@@ -1140,14 +1128,14 @@ bool Parser::isTokIdentifier_in() const {
/// 'null_unspecified'
///
void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
- Declarator::TheContext Context) {
- assert(Context == Declarator::ObjCParameterContext ||
- Context == Declarator::ObjCResultContext);
+ DeclaratorContext Context) {
+ assert(Context == DeclaratorContext::ObjCParameterContext ||
+ Context == DeclaratorContext::ObjCResultContext);
while (1) {
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCPassingType(getCurScope(), DS,
- Context == Declarator::ObjCParameterContext);
+ Context == DeclaratorContext::ObjCParameterContext);
return cutOffParsing();
}
@@ -1205,18 +1193,12 @@ void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
/// Take all the decl attributes out of the given list and add
/// them to the given attribute set.
-static void takeDeclAttributes(ParsedAttributes &attrs,
- AttributeList *list) {
- while (list) {
- AttributeList *cur = list;
- list = cur->getNext();
-
- if (!cur->isUsedAsTypeAttr()) {
- // Clear out the next pointer. We're really completely
- // destroying the internal invariants of the declarator here,
- // but it doesn't matter because we're done with it.
- cur->setNext(nullptr);
- attrs.add(cur);
+static void takeDeclAttributes(ParsedAttributesView &attrs,
+ ParsedAttributesView &from) {
+ for (auto &AL : llvm::reverse(from)) {
+ if (!AL.isUsedAsTypeAttr()) {
+ from.remove(&AL);
+ attrs.addAtStart(&AL);
}
}
}
@@ -1230,11 +1212,10 @@ static void takeDeclAttributes(ParsedAttributes &attrs,
attrs.getPool().takeAllFrom(D.getDeclSpec().getAttributePool());
// Now actually move the attributes over.
- takeDeclAttributes(attrs, D.getDeclSpec().getAttributes().getList());
+ takeDeclAttributes(attrs, D.getMutableDeclSpec().getAttributes());
takeDeclAttributes(attrs, D.getAttributes());
for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
- takeDeclAttributes(attrs,
- const_cast<AttributeList*>(D.getTypeObject(i).getAttrs()));
+ takeDeclAttributes(attrs, D.getTypeObject(i).getAttrs());
}
/// objc-type-name:
@@ -1242,12 +1223,12 @@ static void takeDeclAttributes(ParsedAttributes &attrs,
/// '(' objc-type-qualifiers[opt] ')'
///
ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
- Declarator::TheContext context,
+ DeclaratorContext context,
ParsedAttributes *paramAttrs) {
- assert(context == Declarator::ObjCParameterContext ||
- context == Declarator::ObjCResultContext);
+ assert(context == DeclaratorContext::ObjCParameterContext ||
+ context == DeclaratorContext::ObjCResultContext);
assert((paramAttrs != nullptr) ==
- (context == Declarator::ObjCParameterContext));
+ (context == DeclaratorContext::ObjCParameterContext));
assert(Tok.is(tok::l_paren) && "expected (");
@@ -1265,9 +1246,9 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
// Parse an abstract declarator.
DeclSpec declSpec(AttrFactory);
declSpec.setObjCQualifiers(&DS);
- DeclSpecContext dsContext = DSC_normal;
- if (context == Declarator::ObjCResultContext)
- dsContext = DSC_objc_method_result;
+ DeclSpecContext dsContext = DeclSpecContext::DSC_normal;
+ if (context == DeclaratorContext::ObjCResultContext)
+ dsContext = DeclSpecContext::DSC_objc_method_result;
ParseSpecifierQualifierList(declSpec, AS_none, dsContext);
Declarator declarator(declSpec, context);
ParseDeclarator(declarator);
@@ -1288,7 +1269,7 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
// If we're parsing a parameter, steal all the decl attributes
// and add them to the decl spec.
- if (context == Declarator::ObjCParameterContext)
+ if (context == DeclaratorContext::ObjCParameterContext)
takeDeclAttributes(*paramAttrs, declarator);
}
}
@@ -1352,13 +1333,14 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
ParsedType ReturnType;
ObjCDeclSpec DSRet;
if (Tok.is(tok::l_paren))
- ReturnType = ParseObjCTypeName(DSRet, Declarator::ObjCResultContext,
+ ReturnType = ParseObjCTypeName(DSRet, DeclaratorContext::ObjCResultContext,
nullptr);
// If attributes exist before the method, parse them.
ParsedAttributes methodAttrs(AttrFactory);
if (getLangOpts().ObjC2)
MaybeParseGNUAttributes(methodAttrs);
+ MaybeParseCXX11Attributes(methodAttrs);
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
@@ -1385,15 +1367,13 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
// If attributes exist after the method, parse them.
if (getLangOpts().ObjC2)
MaybeParseGNUAttributes(methodAttrs);
+ MaybeParseCXX11Attributes(methodAttrs);
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
- Decl *Result
- = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
- mType, DSRet, ReturnType,
- selLoc, Sel, nullptr,
- CParamInfo.data(), CParamInfo.size(),
- methodAttrs.getList(), MethodImplKind,
- false, MethodDefinition);
+ Decl *Result = Actions.ActOnMethodDeclaration(
+ getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType,
+ selLoc, Sel, nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs,
+ MethodImplKind, false, MethodDefinition);
PD.complete(Result);
return Result;
}
@@ -1416,16 +1396,15 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
ArgInfo.Type = nullptr;
if (Tok.is(tok::l_paren)) // Parse the argument type if present.
ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec,
- Declarator::ObjCParameterContext,
+ DeclaratorContext::ObjCParameterContext,
&paramAttrs);
// If attributes exist before the argument name, parse them.
// Regardless, collect all the attributes we've parsed so far.
- ArgInfo.ArgAttrs = nullptr;
- if (getLangOpts().ObjC2) {
+ if (getLangOpts().ObjC2)
MaybeParseGNUAttributes(paramAttrs);
- ArgInfo.ArgAttrs = paramAttrs.getList();
- }
+ MaybeParseCXX11Attributes(paramAttrs);
+ ArgInfo.ArgAttrs = paramAttrs;
// Code completion for the next piece of the selector.
if (Tok.is(tok::code_completion)) {
@@ -1494,7 +1473,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS);
// Parse the declarator.
- Declarator ParmDecl(DS, Declarator::PrototypeContext);
+ Declarator ParmDecl(DS, DeclaratorContext::PrototypeContext);
ParseDeclarator(ParmDecl);
IdentifierInfo *ParmII = ParmDecl.getIdentifier();
Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
@@ -1508,20 +1487,18 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
// If attributes exist after the method, parse them.
if (getLangOpts().ObjC2)
MaybeParseGNUAttributes(methodAttrs);
-
+ MaybeParseCXX11Attributes(methodAttrs);
+
if (KeyIdents.size() == 0)
return nullptr;
Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
&KeyIdents[0]);
- Decl *Result
- = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
- mType, DSRet, ReturnType,
- KeyLocs, Sel, &ArgInfos[0],
- CParamInfo.data(), CParamInfo.size(),
- methodAttrs.getList(),
- MethodImplKind, isVariadic, MethodDefinition);
-
+ Decl *Result = Actions.ActOnMethodDeclaration(
+ getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs,
+ Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs,
+ MethodImplKind, isVariadic, MethodDefinition);
+
PD.complete(Result);
return Result;
}
@@ -1703,7 +1680,7 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers(
typeArg, Actions.getASTContext().getPrintingPolicy());
// Form a declarator to turn this into a type.
- Declarator D(DS, Declarator::TypeNameContext);
+ Declarator D(DS, DeclaratorContext::TypeNameContext);
TypeResult fullTypeArg = Actions.ActOnTypeName(getCurScope(), D);
if (fullTypeArg.isUsable()) {
typeArgs.push_back(fullTypeArg.get());
@@ -1886,9 +1863,9 @@ void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocatio
Actions.ActOnObjCContainerFinishDefinition();
// Call ActOnFields() even if we don't have any decls. This is useful
// for code rewriting tools that need to be aware of the empty list.
- Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl,
- AllIvarDecls,
- T.getOpenLocation(), T.getCloseLocation(), nullptr);
+ Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl, AllIvarDecls,
+ T.getOpenLocation(), T.getCloseLocation(),
+ ParsedAttributesView());
}
/// objc-class-instance-variables:
@@ -2038,8 +2015,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol.
IdentifierLocPair ProtoInfo(protocolName, nameLoc);
- return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo,
- attrs.getList());
+ return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs);
}
CheckNestedObjCContexts(AtLoc);
@@ -2066,8 +2042,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol"))
return nullptr;
- return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs,
- attrs.getList());
+ return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs);
}
// Last, and definitely not least, parse a protocol declaration.
@@ -2081,12 +2056,9 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
/*consumeLastToken=*/true))
return nullptr;
- Decl *ProtoType =
- Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
- ProtocolRefs.data(),
- ProtocolRefs.size(),
- ProtocolLocs.data(),
- EndProtoLoc, attrs.getList());
+ Decl *ProtoType = Actions.ActOnStartProtocolInterface(
+ AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(),
+ ProtocolLocs.data(), EndProtoLoc, attrs);
ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
return Actions.ConvertDeclToDeclGroup(ProtoType);
@@ -2273,7 +2245,7 @@ void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
false/*c-functions*/);
- /// \brief Clear and free the cached objc methods.
+ /// Clear and free the cached objc methods.
for (LateParsedObjCMethodContainer::iterator
I = LateParsedObjCMethods.begin(),
E = LateParsedObjCMethods.end(); I != E; ++I)
@@ -2543,7 +2515,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
if (Tok.isNot(tok::ellipsis)) {
DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS);
- Declarator ParmDecl(DS, Declarator::ObjCCatchContext);
+ Declarator ParmDecl(DS, DeclaratorContext::ObjCCatchContext);
ParseDeclarator(ParmDecl);
// Inform the actions module about the declarator, so it
@@ -2586,13 +2558,26 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
ParseScope FinallyScope(this,
Scope::DeclScope | Scope::CompoundStmtScope);
+ bool ShouldCapture =
+ getTargetInfo().getTriple().isWindowsMSVCEnvironment();
+ if (ShouldCapture)
+ Actions.ActOnCapturedRegionStart(Tok.getLocation(), getCurScope(),
+ CR_ObjCAtFinally, 1);
+
StmtResult FinallyBody(true);
if (Tok.is(tok::l_brace))
FinallyBody = ParseCompoundStatementBody();
else
Diag(Tok, diag::err_expected) << tok::l_brace;
- if (FinallyBody.isInvalid())
+
+ if (FinallyBody.isInvalid()) {
FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
+ if (ShouldCapture)
+ Actions.ActOnCapturedRegionError();
+ } else if (ShouldCapture) {
+ FinallyBody = Actions.ActOnCapturedRegionEnd(FinallyBody.get());
+ }
+
FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
FinallyBody.get());
catch_or_finally_seen = true;
@@ -2681,7 +2666,7 @@ void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
Decl *Parser::ParseObjCMethodDefinition() {
Decl *MDecl = ParseObjCMethodPrototype();
- PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(),
+ PrettyDeclStackTraceEntry CrashInfo(Actions.Context, MDecl, Tok.getLocation(),
"parsing Objective-C method");
// parse optional ';'
@@ -2865,7 +2850,7 @@ ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
}
}
-/// \brief Parse the receiver of an Objective-C++ message send.
+/// Parse the receiver of an Objective-C++ message send.
///
/// This routine parses the receiver of a message send in
/// Objective-C++ either as a type or as an expression. Note that this
@@ -2945,7 +2930,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
// We have a class message. Turn the simple-type-specifier or
// typename-specifier we parsed into a type and parse the
// remainder of the class message.
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+ Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
if (Type.isInvalid())
return true;
@@ -2955,7 +2940,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
return false;
}
-/// \brief Determine whether the parser is currently referring to a an
+/// Determine whether the parser is currently referring to a an
/// Objective-C message send, using a simplified heuristic to avoid overhead.
///
/// This routine will only return true for a subset of valid message-send
@@ -3100,7 +3085,7 @@ ExprResult Parser::ParseObjCMessageExpression() {
Res.get());
}
-/// \brief Parse the remainder of an Objective-C message following the
+/// Parse the remainder of an Objective-C message following the
/// '[' objc-receiver.
///
/// This routine handles sends to super, class messages (sent to a
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index a67a5bbe0dea..a413e96a91e7 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
/// \file
-/// \brief This file implements parsing of all OpenMP directives and clauses.
+/// This file implements parsing of all OpenMP directives and clauses.
///
//===----------------------------------------------------------------------===//
@@ -80,51 +80,56 @@ static unsigned getOpenMPDirectiveKindEx(StringRef S) {
.Default(OMPD_unknown);
}
-static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
+static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) {
// Array of foldings: F[i][0] F[i][1] ===> F[i][2].
// E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
// TODO: add other combined directives in topological order.
static const unsigned F[][3] = {
- { OMPD_cancellation, OMPD_point, OMPD_cancellation_point },
- { OMPD_declare, OMPD_reduction, OMPD_declare_reduction },
- { OMPD_declare, OMPD_simd, OMPD_declare_simd },
- { OMPD_declare, OMPD_target, OMPD_declare_target },
- { OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel },
- { OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for },
- { OMPD_distribute_parallel_for, OMPD_simd,
- OMPD_distribute_parallel_for_simd },
- { OMPD_distribute, OMPD_simd, OMPD_distribute_simd },
- { OMPD_end, OMPD_declare, OMPD_end_declare },
- { OMPD_end_declare, OMPD_target, OMPD_end_declare_target },
- { OMPD_target, OMPD_data, OMPD_target_data },
- { OMPD_target, OMPD_enter, OMPD_target_enter },
- { OMPD_target, OMPD_exit, OMPD_target_exit },
- { OMPD_target, OMPD_update, OMPD_target_update },
- { OMPD_target_enter, OMPD_data, OMPD_target_enter_data },
- { OMPD_target_exit, OMPD_data, OMPD_target_exit_data },
- { OMPD_for, OMPD_simd, OMPD_for_simd },
- { OMPD_parallel, OMPD_for, OMPD_parallel_for },
- { OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd },
- { OMPD_parallel, OMPD_sections, OMPD_parallel_sections },
- { OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd },
- { OMPD_target, OMPD_parallel, OMPD_target_parallel },
- { OMPD_target, OMPD_simd, OMPD_target_simd },
- { OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for },
- { OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd },
- { OMPD_teams, OMPD_distribute, OMPD_teams_distribute },
- { OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd },
- { OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel },
- { OMPD_teams_distribute_parallel, OMPD_for, OMPD_teams_distribute_parallel_for },
- { OMPD_teams_distribute_parallel_for, OMPD_simd, OMPD_teams_distribute_parallel_for_simd },
- { OMPD_target, OMPD_teams, OMPD_target_teams },
- { OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute },
- { OMPD_target_teams_distribute, OMPD_parallel, OMPD_target_teams_distribute_parallel },
- { OMPD_target_teams_distribute, OMPD_simd, OMPD_target_teams_distribute_simd },
- { OMPD_target_teams_distribute_parallel, OMPD_for, OMPD_target_teams_distribute_parallel_for },
- { OMPD_target_teams_distribute_parallel_for, OMPD_simd, OMPD_target_teams_distribute_parallel_for_simd }
- };
+ {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
+ {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
+ {OMPD_declare, OMPD_simd, OMPD_declare_simd},
+ {OMPD_declare, OMPD_target, OMPD_declare_target},
+ {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
+ {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
+ {OMPD_distribute_parallel_for, OMPD_simd,
+ OMPD_distribute_parallel_for_simd},
+ {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
+ {OMPD_end, OMPD_declare, OMPD_end_declare},
+ {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
+ {OMPD_target, OMPD_data, OMPD_target_data},
+ {OMPD_target, OMPD_enter, OMPD_target_enter},
+ {OMPD_target, OMPD_exit, OMPD_target_exit},
+ {OMPD_target, OMPD_update, OMPD_target_update},
+ {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
+ {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
+ {OMPD_for, OMPD_simd, OMPD_for_simd},
+ {OMPD_parallel, OMPD_for, OMPD_parallel_for},
+ {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
+ {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
+ {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
+ {OMPD_target, OMPD_parallel, OMPD_target_parallel},
+ {OMPD_target, OMPD_simd, OMPD_target_simd},
+ {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
+ {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
+ {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
+ {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
+ {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
+ {OMPD_teams_distribute_parallel, OMPD_for,
+ OMPD_teams_distribute_parallel_for},
+ {OMPD_teams_distribute_parallel_for, OMPD_simd,
+ OMPD_teams_distribute_parallel_for_simd},
+ {OMPD_target, OMPD_teams, OMPD_target_teams},
+ {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
+ {OMPD_target_teams_distribute, OMPD_parallel,
+ OMPD_target_teams_distribute_parallel},
+ {OMPD_target_teams_distribute, OMPD_simd,
+ OMPD_target_teams_distribute_simd},
+ {OMPD_target_teams_distribute_parallel, OMPD_for,
+ OMPD_target_teams_distribute_parallel_for},
+ {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
+ OMPD_target_teams_distribute_parallel_for_simd}};
enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
- auto Tok = P.getCurToken();
+ Token Tok = P.getCurToken();
unsigned DKind =
Tok.isAnnotation()
? static_cast<unsigned>(OMPD_unknown)
@@ -132,8 +137,8 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
if (DKind == OMPD_unknown)
return OMPD_unknown;
- for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
- if (DKind != F[i][0])
+ for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
+ if (DKind != F[I][0])
continue;
Tok = P.getPreprocessor().LookAhead(0);
@@ -144,9 +149,9 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
if (SDKind == OMPD_unknown)
continue;
- if (SDKind == F[i][1]) {
+ if (SDKind == F[I][1]) {
P.ConsumeToken();
- DKind = F[i][2];
+ DKind = F[I][2];
}
}
return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
@@ -205,7 +210,7 @@ static DeclarationName parseOpenMPReductionId(Parser &P) {
: DeclNames.getCXXOperatorName(OOK);
}
-/// \brief Parse 'omp declare reduction' construct.
+/// Parse 'omp declare reduction' construct.
///
/// declare-reduction-directive:
/// annot_pragma_openmp 'declare' 'reduction'
@@ -250,9 +255,10 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
do {
ColonProtectionRAIIObject ColonRAII(*this);
SourceRange Range;
- TypeResult TR = ParseTypeName(&Range, Declarator::PrototypeContext, AS);
+ TypeResult TR =
+ ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
if (TR.isUsable()) {
- auto ReductionType =
+ QualType ReductionType =
Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
if (!ReductionType.isNull()) {
ReductionTypes.push_back(
@@ -299,7 +305,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
// Parse <combiner> expression and then parse initializer if any for each
// correct type.
unsigned I = 0, E = ReductionTypes.size();
- for (auto *D : DRD.get()) {
+ for (Decl *D : DRD.get()) {
TentativeParsingAction TPA(*this);
ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
Scope::CompoundStmtScope |
@@ -322,9 +328,9 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
// Parse <initializer> expression.
if (Tok.is(tok::identifier) &&
- Tok.getIdentifierInfo()->isStr("initializer"))
+ Tok.getIdentifierInfo()->isStr("initializer")) {
ConsumeToken();
- else {
+ } else {
Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
TPA.Commit();
IsCorrect = false;
@@ -418,13 +424,15 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
} else {
// Match the ')'.
- T.consumeClose();
+ SourceLocation RLoc = Tok.getLocation();
+ if (!T.consumeClose())
+ RLoc = T.getCloseLocation();
assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
"Unexpected number of commas!");
- ExprResult Initializer = Actions.ActOnParenListExpr(
- T.getOpenLocation(), T.getCloseLocation(), Exprs);
+ ExprResult Initializer =
+ Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
/*DirectInit=*/true);
}
@@ -550,7 +558,7 @@ static bool parseDeclareSimdClauses(
if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
CKind == OMPC_linear) {
Parser::OpenMPVarListDataTy Data;
- auto *Vars = &Uniforms;
+ SmallVectorImpl<Expr *> *Vars = &Uniforms;
if (CKind == OMPC_aligned)
Vars = &Aligneds;
else if (CKind == OMPC_linear)
@@ -560,9 +568,9 @@ static bool parseDeclareSimdClauses(
if (P.ParseOpenMPVarList(OMPD_declare_simd,
getOpenMPClauseKind(ClauseName), *Vars, Data))
IsError = true;
- if (CKind == OMPC_aligned)
+ if (CKind == OMPC_aligned) {
Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
- else if (CKind == OMPC_linear) {
+ } else if (CKind == OMPC_linear) {
if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind,
Data.DepLinMapLoc))
Data.LinKind = OMPC_LINEAR_val;
@@ -612,15 +620,14 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
}
// Skip the last annot_pragma_openmp_end.
SourceLocation EndLoc = ConsumeAnnotationToken();
- if (!IsError) {
- return Actions.ActOnOpenMPDeclareSimdDirective(
- Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
- LinModifiers, Steps, SourceRange(Loc, EndLoc));
- }
- return Ptr;
+ if (IsError)
+ return Ptr;
+ return Actions.ActOnOpenMPDeclareSimdDirective(
+ Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
+ LinModifiers, Steps, SourceRange(Loc, EndLoc));
}
-/// \brief Parsing of declarative OpenMP directives.
+/// Parsing of declarative OpenMP directives.
///
/// threadprivate-directive:
/// annot_pragma_openmp 'threadprivate' simple-variable-list
@@ -642,7 +649,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
ParenBraceBracketBalancer BalancerRAIIObj(*this);
SourceLocation Loc = ConsumeAnnotationToken();
- auto DKind = ParseOpenMPDirectiveKind(*this);
+ OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
switch (DKind) {
case OMPD_threadprivate: {
@@ -665,7 +672,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
}
case OMPD_declare_reduction:
ConsumeToken();
- if (auto Res = ParseOpenMPDeclareReductionDirective(AS)) {
+ if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
// The last seen token is annot_pragma_openmp_end - need to check for
// extra tokens.
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
@@ -694,9 +701,9 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
ConsumeAnyToken();
DeclGroupPtrTy Ptr;
- if (Tok.is(tok::annot_pragma_openmp))
+ if (Tok.is(tok::annot_pragma_openmp)) {
Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
- else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
+ } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
// Here we expect to see some function declaration.
if (AS == AS_none) {
assert(TagType == DeclSpec::TST_unspecified);
@@ -718,7 +725,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
SourceLocation DTLoc = ConsumeAnyToken();
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
// OpenMP 4.5 syntax with list of entities.
- llvm::SmallSetVector<const NamedDecl*, 16> SameDirectiveDecls;
+ Sema::NamedDeclSetType SameDirectiveDecls;
while (Tok.isNot(tok::annot_pragma_openmp_end)) {
OMPDeclareTargetDeclAttr::MapTypeTy MT =
OMPDeclareTargetDeclAttr::MT_To;
@@ -734,12 +741,13 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
}
ConsumeToken();
}
- auto Callback = [this, MT, &SameDirectiveDecls](
- CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
+ auto &&Callback = [this, MT, &SameDirectiveDecls](
+ CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
SameDirectiveDecls);
};
- if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback, true))
+ if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
+ /*AllowScopeSpecifier=*/true))
break;
// Consume optional ','.
@@ -748,7 +756,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
}
SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
ConsumeAnyToken();
- return DeclGroupPtrTy();
+ SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
+ SameDirectiveDecls.end());
+ if (Decls.empty())
+ return DeclGroupPtrTy();
+ return Actions.BuildDeclaratorGroup(Decls);
}
// Skip the last annot_pragma_openmp_end.
@@ -757,7 +769,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
return DeclGroupPtrTy();
- DKind = ParseOpenMPDirectiveKind(*this);
+ llvm::SmallVector<Decl *, 4> Decls;
+ DKind = parseOpenMPDirectiveKind(*this);
while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target &&
Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) {
DeclGroupPtrTy Ptr;
@@ -771,10 +784,14 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
Ptr =
ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
}
+ if (Ptr) {
+ DeclGroupRef Ref = Ptr.get();
+ Decls.append(Ref.begin(), Ref.end());
+ }
if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
TentativeParsingAction TPA(*this);
ConsumeAnnotationToken();
- DKind = ParseOpenMPDirectiveKind(*this);
+ DKind = parseOpenMPDirectiveKind(*this);
if (DKind != OMPD_end_declare_target)
TPA.Revert();
else
@@ -796,7 +813,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
}
Actions.ActOnFinishOpenMPDeclareTargetDirective();
- return DeclGroupPtrTy();
+ return Actions.BuildDeclaratorGroup(Decls);
}
case OMPD_unknown:
Diag(Tok, diag::err_omp_unknown_directive);
@@ -850,7 +867,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
case OMPD_target_teams_distribute_parallel_for_simd:
case OMPD_target_teams_distribute_simd:
Diag(Tok, diag::err_omp_unexpected_directive)
- << getOpenMPDirectiveName(DKind);
+ << 1 << getOpenMPDirectiveName(DKind);
break;
}
while (Tok.isNot(tok::annot_pragma_openmp_end))
@@ -859,7 +876,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
return nullptr;
}
-/// \brief Parsing of declarative or executable OpenMP directives.
+/// Parsing of declarative or executable OpenMP directives.
///
/// threadprivate-directive:
/// annot_pragma_openmp 'threadprivate' simple-variable-list
@@ -902,7 +919,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
- auto DKind = ParseOpenMPDirectiveKind(*this);
+ OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
OpenMPDirectiveKind CancelRegion = OMPD_unknown;
// Name of critical directive.
DeclarationNameInfo DirName;
@@ -935,7 +952,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
}
case OMPD_declare_reduction:
ConsumeToken();
- if (auto Res = ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
+ if (DeclGroupPtrTy Res =
+ ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
// The last seen token is annot_pragma_openmp_end - need to check for
// extra tokens.
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
@@ -946,8 +964,9 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
}
ConsumeAnyToken();
Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
- } else
+ } else {
SkipUntil(tok::annot_pragma_openmp_end);
+ }
break;
case OMPD_flush:
if (PP.LookAhead(0).is(tok::l_paren)) {
@@ -1026,7 +1045,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
T.consumeClose();
}
} else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
- CancelRegion = ParseOpenMPDirectiveKind(*this);
+ CancelRegion = parseOpenMPDirectiveKind(*this);
if (Tok.isNot(tok::annot_pragma_openmp_end))
ConsumeToken();
}
@@ -1079,21 +1098,18 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
StmtResult AssociatedStmt;
if (HasAssociatedStatement) {
// The body is a block scope like in Lambdas and Blocks.
- Sema::CompoundScopeRAII CompoundScope(Actions);
Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
- Actions.ActOnStartOfCompoundStmt();
- // Parse statement
- AssociatedStmt = ParseStatement();
- Actions.ActOnFinishOfCompoundStmt();
+ // FIXME: We create a bogus CompoundStmt scope to hold the contents of
+ // the captured region. Code elsewhere assumes that any FunctionScopeInfo
+ // should have at least one compound statement scope within it.
+ AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
} else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
DKind == OMPD_target_exit_data) {
- Sema::CompoundScopeRAII CompoundScope(Actions);
Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
- Actions.ActOnStartOfCompoundStmt();
- AssociatedStmt =
- Actions.ActOnCompoundStmt(Loc, Loc, llvm::None, /*isStmtExpr=*/false);
- Actions.ActOnFinishOfCompoundStmt();
+ AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
+ Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
+ /*isStmtExpr=*/false));
AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
}
Directive = Actions.ActOnOpenMPExecutableDirective(
@@ -1109,7 +1125,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
case OMPD_declare_target:
case OMPD_end_declare_target:
Diag(Tok, diag::err_omp_unexpected_directive)
- << getOpenMPDirectiveName(DKind);
+ << 1 << getOpenMPDirectiveName(DKind);
SkipUntil(tok::annot_pragma_openmp_end);
break;
case OMPD_unknown:
@@ -1140,7 +1156,6 @@ bool Parser::ParseOpenMPSimpleVarList(
// Read tokens while ')' or annot_pragma_openmp_end is not found.
while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
CXXScopeSpec SS;
- SourceLocation TemplateKWLoc;
UnqualifiedId Name;
// Read var name.
Token PrevTok = Tok;
@@ -1152,7 +1167,7 @@ bool Parser::ParseOpenMPSimpleVarList(
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
} else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
- TemplateKWLoc, Name)) {
+ nullptr, Name)) {
IsCorrect = false;
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
@@ -1184,7 +1199,7 @@ bool Parser::ParseOpenMPSimpleVarList(
return !IsCorrect;
}
-/// \brief Parsing of OpenMP clauses.
+/// Parsing of OpenMP clauses.
///
/// clause:
/// if-clause | final-clause | num_threads-clause | safelen-clause |
@@ -1204,11 +1219,13 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind, bool FirstClause) {
OMPClause *Clause = nullptr;
bool ErrorFound = false;
+ bool WrongDirective = false;
// Check if clause is allowed for the given directive.
if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
<< getOpenMPDirectiveName(DKind);
ErrorFound = true;
+ WrongDirective = true;
}
switch (CKind) {
@@ -1252,9 +1269,9 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
}
if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
- Clause = ParseOpenMPClause(CKind);
+ Clause = ParseOpenMPClause(CKind, WrongDirective);
else
- Clause = ParseOpenMPSingleExprClause(CKind);
+ Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
break;
case OMPC_default:
case OMPC_proc_bind:
@@ -1269,7 +1286,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
ErrorFound = true;
}
- Clause = ParseOpenMPSimpleClause(CKind);
+ Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
break;
case OMPC_schedule:
case OMPC_dist_schedule:
@@ -1286,7 +1303,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
LLVM_FALLTHROUGH;
case OMPC_if:
- Clause = ParseOpenMPSingleExprWithArgClause(CKind);
+ Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
break;
case OMPC_nowait:
case OMPC_untied:
@@ -1309,7 +1326,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
ErrorFound = true;
}
- Clause = ParseOpenMPClause(CKind);
+ Clause = ParseOpenMPClause(CKind, WrongDirective);
break;
case OMPC_private:
case OMPC_firstprivate:
@@ -1329,7 +1346,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
- Clause = ParseOpenMPVarListClause(DKind, CKind);
+ Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
break;
case OMPC_unknown:
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
@@ -1338,8 +1355,9 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
break;
case OMPC_threadprivate:
case OMPC_uniform:
- Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
- << getOpenMPDirectiveName(DKind);
+ if (!WrongDirective)
+ Diag(Tok, diag::err_omp_unexpected_clause)
+ << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
break;
}
@@ -1362,13 +1380,14 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
// Parse ')'.
- T.consumeClose();
+ RLoc = Tok.getLocation();
+ if (!T.consumeClose())
+ RLoc = T.getCloseLocation();
- RLoc = T.getCloseLocation();
return Val;
}
-/// \brief Parsing of OpenMP clauses with single expressions like 'final',
+/// Parsing of OpenMP clauses with single expressions like 'final',
/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
///
@@ -1399,7 +1418,8 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
/// hint-clause:
/// 'hint' '(' expression ')'
///
-OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
+OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
+ bool ParseOnly) {
SourceLocation Loc = ConsumeToken();
SourceLocation LLoc = Tok.getLocation();
SourceLocation RLoc;
@@ -1409,10 +1429,12 @@ OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
if (Val.isInvalid())
return nullptr;
+ if (ParseOnly)
+ return nullptr;
return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
}
-/// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
+/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
///
/// default-clause:
/// 'default' '(' 'none' | 'shared' ')
@@ -1420,7 +1442,8 @@ OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
/// proc_bind-clause:
/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
///
-OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
+OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
+ bool ParseOnly) {
SourceLocation Loc = Tok.getLocation();
SourceLocation LOpen = ConsumeToken();
// Parse '('.
@@ -1437,13 +1460,16 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
ConsumeAnyToken();
// Parse ')'.
- T.consumeClose();
+ SourceLocation RLoc = Tok.getLocation();
+ if (!T.consumeClose())
+ RLoc = T.getCloseLocation();
- return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
- Tok.getLocation());
+ if (ParseOnly)
+ return nullptr;
+ return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, RLoc);
}
-/// \brief Parsing of OpenMP clauses like 'ordered'.
+/// Parsing of OpenMP clauses like 'ordered'.
///
/// ordered-clause:
/// 'ordered'
@@ -1469,15 +1495,17 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
/// nogroup-clause:
/// 'nogroup'
///
-OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
+OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
SourceLocation Loc = Tok.getLocation();
ConsumeAnyToken();
+ if (ParseOnly)
+ return nullptr;
return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
}
-/// \brief Parsing of OpenMP clauses with single expressions and some additional
+/// Parsing of OpenMP clauses with single expressions and some additional
/// argument like 'schedule' or 'dist_schedule'.
///
/// schedule-clause:
@@ -1490,7 +1518,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
/// defaultmap:
/// 'defaultmap' '(' modifier ':' kind ')'
///
-OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
+OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
+ bool ParseOnly) {
SourceLocation Loc = ConsumeToken();
SourceLocation DelimLoc;
// Parse '('.
@@ -1509,7 +1538,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
- auto KindModifier = getOpenMPSimpleClauseType(
+ unsigned KindModifier = getOpenMPSimpleClauseType(
Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
if (KindModifier > OMPC_SCHEDULE_unknown) {
// Parse 'modifier'
@@ -1582,7 +1611,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
assert(Kind == OMPC_if);
KLoc.push_back(Tok.getLocation());
TentativeParsingAction TPA(*this);
- Arg.push_back(ParseOpenMPDirectiveKind(*this));
+ Arg.push_back(parseOpenMPDirectiveKind(*this));
if (Arg.back() != OMPD_unknown) {
ConsumeToken();
if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
@@ -1592,8 +1621,9 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
TPA.Revert();
Arg.back() = OMPD_unknown;
}
- } else
+ } else {
TPA.Revert();
+ }
}
bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
@@ -1607,19 +1637,21 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
}
// Parse ')'.
- T.consumeClose();
+ SourceLocation RLoc = Tok.getLocation();
+ if (!T.consumeClose())
+ RLoc = T.getCloseLocation();
if (NeedAnExpression && Val.isInvalid())
return nullptr;
+ if (ParseOnly)
+ return nullptr;
return Actions.ActOnOpenMPSingleExprWithArgClause(
- Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
- T.getCloseLocation());
+ Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
}
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
UnqualifiedId &ReductionId) {
- SourceLocation TemplateKWLoc;
if (ReductionIdScopeSpec.isEmpty()) {
auto OOK = OO_None;
switch (P.getCurToken().getKind()) {
@@ -1661,7 +1693,7 @@ static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
/*AllowDestructorName*/ false,
/*AllowConstructorName*/ false,
/*AllowDeductionGuide*/ false,
- nullptr, TemplateKWLoc, ReductionId);
+ nullptr, nullptr, ReductionId);
}
/// Parses clauses with list.
@@ -1723,9 +1755,9 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
return false;
}
}
- if (Tok.is(tok::colon))
+ if (Tok.is(tok::colon)) {
Data.ColonLoc = ConsumeToken();
- else {
+ } else {
Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
: diag::warn_pragma_expected_colon)
<< "dependency type";
@@ -1774,8 +1806,9 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
if (Data.MapTypeModifier != OMPC_MAP_always) {
Diag(Tok, diag::err_omp_unknown_map_type_modifier);
Data.MapTypeModifier = OMPC_MAP_unknown;
- } else
+ } else {
MapTypeModifierSpecified = true;
+ }
ConsumeToken();
ConsumeToken();
@@ -1799,8 +1832,9 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
if (Data.MapTypeModifier != OMPC_MAP_always) {
Diag(Tok, diag::err_omp_unknown_map_type_modifier);
Data.MapTypeModifier = OMPC_MAP_unknown;
- } else
+ } else {
MapTypeModifierSpecified = true;
+ }
ConsumeToken();
@@ -1847,9 +1881,9 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
// Parse variable
ExprResult VarExpr =
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
- if (VarExpr.isUsable())
+ if (VarExpr.isUsable()) {
Vars.push_back(VarExpr.get());
- else {
+ } else {
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
}
@@ -1885,16 +1919,16 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
}
// Parse ')'.
- T.consumeClose();
- if ((Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
- Vars.empty()) ||
- (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
- (MustHaveTail && !Data.TailExpr) || InvalidReductionId)
- return true;
- return false;
+ Data.RLoc = Tok.getLocation();
+ if (!T.consumeClose())
+ Data.RLoc = T.getCloseLocation();
+ return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
+ Vars.empty()) ||
+ (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
+ (MustHaveTail && !Data.TailExpr) || InvalidReductionId;
}
-/// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
+/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
/// 'in_reduction'.
///
@@ -1939,7 +1973,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
/// modifier(list)
/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
- OpenMPClauseKind Kind) {
+ OpenMPClauseKind Kind,
+ bool ParseOnly) {
SourceLocation Loc = Tok.getLocation();
SourceLocation LOpen = ConsumeToken();
SmallVector<Expr *, 4> Vars;
@@ -1948,8 +1983,10 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
return nullptr;
+ if (ParseOnly)
+ return nullptr;
return Actions.ActOnOpenMPVarListClause(
- Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Tok.getLocation(),
+ Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Data.RLoc,
Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind,
Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit,
Data.DepLinMapLoc);
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 198d5c6e9cb0..9a25f9c25c03 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -95,6 +95,44 @@ struct PragmaFPContractHandler : public PragmaHandler {
Token &FirstToken) override;
};
+// Pragma STDC implementations.
+
+/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
+struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
+ PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
+
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &Tok) override {
+ tok::OnOffSwitch OOS;
+ if (PP.LexOnOffSwitch(OOS))
+ return;
+ if (OOS == tok::OOS_ON)
+ PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
+ }
+};
+
+/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
+struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
+ PragmaSTDC_CX_LIMITED_RANGEHandler() : PragmaHandler("CX_LIMITED_RANGE") {}
+
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &Tok) override {
+ tok::OnOffSwitch OOS;
+ PP.LexOnOffSwitch(OOS);
+ }
+};
+
+/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
+struct PragmaSTDC_UnknownHandler : public PragmaHandler {
+ PragmaSTDC_UnknownHandler() = default;
+
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &UnknownTok) override {
+ // C99 6.10.6p2, unknown forms are not allowed.
+ PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
+ }
+};
+
struct PragmaFPHandler : public PragmaHandler {
PragmaFPHandler() : PragmaHandler("fp") {}
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
@@ -182,6 +220,12 @@ struct PragmaMSIntrinsicHandler : public PragmaHandler {
Token &FirstToken) override;
};
+struct PragmaMSOptimizeHandler : public PragmaHandler {
+ PragmaMSOptimizeHandler() : PragmaHandler("optimize") {}
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &FirstToken) override;
+};
+
struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler {
PragmaForceCUDAHostDeviceHandler(Sema &Actions)
: PragmaHandler("force_cuda_host_device"), Actions(Actions) {}
@@ -233,6 +277,15 @@ void Parser::initializePragmaHandlers() {
FPContractHandler.reset(new PragmaFPContractHandler());
PP.AddPragmaHandler("STDC", FPContractHandler.get());
+ STDCFENVHandler.reset(new PragmaSTDC_FENV_ACCESSHandler());
+ PP.AddPragmaHandler("STDC", STDCFENVHandler.get());
+
+ STDCCXLIMITHandler.reset(new PragmaSTDC_CX_LIMITED_RANGEHandler());
+ PP.AddPragmaHandler("STDC", STDCCXLIMITHandler.get());
+
+ STDCUnknownHandler.reset(new PragmaSTDC_UnknownHandler());
+ PP.AddPragmaHandler("STDC", STDCUnknownHandler.get());
+
PCSectionHandler.reset(new PragmaClangSectionHandler(Actions));
PP.AddPragmaHandler("clang", PCSectionHandler.get());
@@ -248,7 +301,8 @@ void Parser::initializePragmaHandlers() {
OpenMPHandler.reset(new PragmaNoOpenMPHandler());
PP.AddPragmaHandler(OpenMPHandler.get());
- if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
+ if (getLangOpts().MicrosoftExt ||
+ getTargetInfo().getTriple().isOSBinFormatELF()) {
MSCommentHandler.reset(new PragmaCommentHandler(Actions));
PP.AddPragmaHandler(MSCommentHandler.get());
}
@@ -276,6 +330,8 @@ void Parser::initializePragmaHandlers() {
PP.AddPragmaHandler(MSRuntimeChecks.get());
MSIntrinsic.reset(new PragmaMSIntrinsicHandler());
PP.AddPragmaHandler(MSIntrinsic.get());
+ MSOptimize.reset(new PragmaMSOptimizeHandler());
+ PP.AddPragmaHandler(MSOptimize.get());
}
if (getLangOpts().CUDA) {
@@ -330,7 +386,8 @@ void Parser::resetPragmaHandlers() {
PP.RemovePragmaHandler(OpenMPHandler.get());
OpenMPHandler.reset();
- if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
+ if (getLangOpts().MicrosoftExt ||
+ getTargetInfo().getTriple().isOSBinFormatELF()) {
PP.RemovePragmaHandler(MSCommentHandler.get());
MSCommentHandler.reset();
}
@@ -361,6 +418,8 @@ void Parser::resetPragmaHandlers() {
MSRuntimeChecks.reset();
PP.RemovePragmaHandler(MSIntrinsic.get());
MSIntrinsic.reset();
+ PP.RemovePragmaHandler(MSOptimize.get());
+ MSOptimize.reset();
}
if (getLangOpts().CUDA) {
@@ -371,6 +430,15 @@ void Parser::resetPragmaHandlers() {
PP.RemovePragmaHandler("STDC", FPContractHandler.get());
FPContractHandler.reset();
+ PP.RemovePragmaHandler("STDC", STDCFENVHandler.get());
+ STDCFENVHandler.reset();
+
+ PP.RemovePragmaHandler("STDC", STDCCXLIMITHandler.get());
+ STDCCXLIMITHandler.reset();
+
+ PP.RemovePragmaHandler("STDC", STDCUnknownHandler.get());
+ STDCUnknownHandler.reset();
+
PP.RemovePragmaHandler("clang", OptimizeHandler.get());
OptimizeHandler.reset();
@@ -390,7 +458,7 @@ void Parser::resetPragmaHandlers() {
AttributePragmaHandler.reset();
}
-/// \brief Handle the annotation token produced for #pragma unused(...)
+/// Handle the annotation token produced for #pragma unused(...)
///
/// Each annot_pragma_unused is followed by the argument token so e.g.
/// "#pragma unused(x,y)" becomes:
@@ -451,8 +519,10 @@ void Parser::HandlePragmaAlign() {
Sema::PragmaOptionsAlignKind Kind =
static_cast<Sema::PragmaOptionsAlignKind>(
reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
- SourceLocation PragmaLoc = ConsumeAnnotationToken();
- Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
+ Actions.ActOnPragmaOptionsAlign(Kind, Tok.getLocation());
+ // Consume the token after processing the pragma to enable pragma-specific
+ // #include warnings.
+ ConsumeAnnotationToken();
}
void Parser::HandlePragmaDump() {
@@ -1175,7 +1245,7 @@ bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
namespace {
-/// Describes the stage at which attribute subject rule parsing was interruped.
+/// Describes the stage at which attribute subject rule parsing was interrupted.
enum class MissingAttributeSubjectRulesRecoveryPoint {
Comma,
ApplyTo,
@@ -1201,7 +1271,7 @@ getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
/// suggests the possible attribute subject rules in a fix-it together with
/// any other missing tokens.
DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
- unsigned DiagID, AttributeList &Attribute,
+ unsigned DiagID, ParsedAttr &Attribute,
MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) {
SourceLocation Loc = PRef.getEndOfPreviousToken();
if (Loc.isInvalid())
@@ -1301,12 +1371,11 @@ void Parser::HandlePragmaAttribute() {
if (Tok.isNot(tok::l_paren))
Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- AttributeList::AS_GNU);
+ ParsedAttr::AS_GNU);
else
ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
/*ScopeName=*/nullptr,
- /*ScopeLoc=*/SourceLocation(),
- AttributeList::AS_GNU,
+ /*ScopeLoc=*/SourceLocation(), ParsedAttr::AS_GNU,
/*Declarator=*/nullptr);
if (ExpectAndConsume(tok::r_paren))
@@ -1320,9 +1389,9 @@ void Parser::HandlePragmaAttribute() {
if (Tok.getIdentifierInfo()) {
// If we suspect that this is an attribute suggest the use of
// '__attribute__'.
- if (AttributeList::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
- AttributeList::AS_GNU) !=
- AttributeList::UnknownAttribute) {
+ if (ParsedAttr::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
+ ParsedAttr::AS_GNU) !=
+ ParsedAttr::UnknownAttribute) {
SourceLocation InsertStartLoc = Tok.getLocation();
ConsumeToken();
if (Tok.is(tok::l_paren)) {
@@ -1340,26 +1409,26 @@ void Parser::HandlePragmaAttribute() {
return;
}
- if (!Attrs.getList() || Attrs.getList()->isInvalid()) {
+ if (Attrs.empty() || Attrs.begin()->isInvalid()) {
SkipToEnd();
return;
}
// Ensure that we don't have more than one attribute.
- if (Attrs.getList()->getNext()) {
- SourceLocation Loc = Attrs.getList()->getNext()->getLoc();
+ if (Attrs.size() > 1) {
+ SourceLocation Loc = Attrs[1].getLoc();
Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
SkipToEnd();
return;
}
- if (!Attrs.getList()->isSupportedByPragmaAttribute()) {
+ ParsedAttr &Attribute = *Attrs.begin();
+ if (!Attribute.isSupportedByPragmaAttribute()) {
Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
- << Attrs.getList()->getName();
+ << Attribute.getName();
SkipToEnd();
return;
}
- AttributeList &Attribute = *Attrs.getList();
// Parse the subject-list.
if (!TryConsumeToken(tok::comma)) {
@@ -2030,7 +2099,7 @@ PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
StateLoc, State);
}
-/// \brief Handle '#pragma omp ...' when OpenMP is disabled.
+/// Handle '#pragma omp ...' when OpenMP is disabled.
///
void
PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
@@ -2045,7 +2114,7 @@ PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
PP.DiscardUntilEndOfDirective();
}
-/// \brief Handle '#pragma omp ...' when OpenMP is enabled.
+/// Handle '#pragma omp ...' when OpenMP is enabled.
///
void
PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
@@ -2057,9 +2126,21 @@ PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
Tok.setKind(tok::annot_pragma_openmp);
Tok.setLocation(FirstTok.getLocation());
- while (Tok.isNot(tok::eod)) {
+ while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
Pragma.push_back(Tok);
PP.Lex(Tok);
+ if (Tok.is(tok::annot_pragma_openmp)) {
+ PP.Diag(Tok, diag::err_omp_unexpected_directive) << 0;
+ unsigned InnerPragmaCnt = 1;
+ while (InnerPragmaCnt != 0) {
+ PP.Lex(Tok);
+ if (Tok.is(tok::annot_pragma_openmp))
+ ++InnerPragmaCnt;
+ else if (Tok.is(tok::annot_pragma_openmp_end))
+ --InnerPragmaCnt;
+ }
+ PP.Lex(Tok);
+ }
}
SourceLocation EodLoc = Tok.getLocation();
Tok.startToken();
@@ -2073,7 +2154,7 @@ PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
/*DisableMacroExpansion=*/false);
}
-/// \brief Handle '#pragma pointers_to_members'
+/// Handle '#pragma pointers_to_members'
// The grammar for this pragma is as follows:
//
// <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
@@ -2171,7 +2252,7 @@ void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
PP.EnterToken(AnnotTok);
}
-/// \brief Handle '#pragma vtordisp'
+/// Handle '#pragma vtordisp'
// The grammar for this pragma is as follows:
//
// <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
@@ -2264,7 +2345,7 @@ void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
PP.EnterToken(AnnotTok);
}
-/// \brief Handle all MS pragmas. Simply forwards the tokens after inserting
+/// Handle all MS pragmas. Simply forwards the tokens after inserting
/// an annotation token.
void PragmaMSPragma::HandlePragma(Preprocessor &PP,
PragmaIntroducerKind Introducer,
@@ -2282,7 +2363,7 @@ void PragmaMSPragma::HandlePragma(Preprocessor &PP,
TokenVector.push_back(Tok);
AnnotTok.setAnnotationEndLoc(Tok.getLocation());
}
- // Add a sentinal EoF token to the end of the list.
+ // Add a sentinel EoF token to the end of the list.
TokenVector.push_back(EoF);
// We must allocate this array with new because EnterTokenStream is going to
// delete it later.
@@ -2295,7 +2376,7 @@ void PragmaMSPragma::HandlePragma(Preprocessor &PP,
PP.EnterToken(AnnotTok);
}
-/// \brief Handle the Microsoft \#pragma detect_mismatch extension.
+/// Handle the Microsoft \#pragma detect_mismatch extension.
///
/// The syntax is:
/// \code
@@ -2352,7 +2433,7 @@ void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
}
-/// \brief Handle the microsoft \#pragma comment extension.
+/// Handle the microsoft \#pragma comment extension.
///
/// The syntax is:
/// \code
@@ -2393,6 +2474,12 @@ void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
return;
}
+ if (PP.getTargetInfo().getTriple().isOSBinFormatELF() && Kind != PCK_Lib) {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
+ << II->getName();
+ return;
+ }
+
// On PS4, issue a warning about any pragma comments other than
// #pragma comment lib.
if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) {
@@ -2595,7 +2682,7 @@ void Parser::HandlePragmaFP() {
ConsumeAnnotationToken();
}
-/// \brief Parses loop or unroll pragma hint value and fills in Info.
+/// Parses loop or unroll pragma hint value and fills in Info.
static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
Token Option, bool ValueInParens,
PragmaLoopHintInfo &Info) {
@@ -2637,7 +2724,7 @@ static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
return false;
}
-/// \brief Handle the \#pragma clang loop directive.
+/// Handle the \#pragma clang loop directive.
/// #pragma clang 'loop' loop-hints
///
/// loop-hints:
@@ -2752,7 +2839,7 @@ void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
/*DisableMacroExpansion=*/false);
}
-/// \brief Handle the loop unroll optimization pragmas.
+/// Handle the loop unroll optimization pragmas.
/// #pragma unroll
/// #pragma unroll unroll-hint-value
/// #pragma unroll '(' unroll-hint-value ')'
@@ -2822,7 +2909,7 @@ void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
/*DisableMacroExpansion=*/false);
}
-/// \brief Handle the Microsoft \#pragma intrinsic extension.
+/// Handle the Microsoft \#pragma intrinsic extension.
///
/// The syntax is:
/// \code
@@ -2871,6 +2958,61 @@ void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
<< "intrinsic";
}
+
+// #pragma optimize("gsty", on|off)
+void PragmaMSOptimizeHandler::HandlePragma(Preprocessor &PP,
+ PragmaIntroducerKind Introducer,
+ Token &Tok) {
+ SourceLocation StartLoc = Tok.getLocation();
+ PP.Lex(Tok);
+
+ if (Tok.isNot(tok::l_paren)) {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "optimize";
+ return;
+ }
+ PP.Lex(Tok);
+
+ if (Tok.isNot(tok::string_literal)) {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_string) << "optimize";
+ return;
+ }
+ // We could syntax check the string but it's probably not worth the effort.
+ PP.Lex(Tok);
+
+ if (Tok.isNot(tok::comma)) {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_comma) << "optimize";
+ return;
+ }
+ PP.Lex(Tok);
+
+ if (Tok.is(tok::eod) || Tok.is(tok::r_paren)) {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_missing_argument)
+ << "optimize" << /*Expected=*/true << "'on' or 'off'";
+ return;
+ }
+ IdentifierInfo *II = Tok.getIdentifierInfo();
+ if (!II || (!II->isStr("on") && !II->isStr("off"))) {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
+ << PP.getSpelling(Tok) << "optimize" << /*Expected=*/true
+ << "'on' or 'off'";
+ return;
+ }
+ PP.Lex(Tok);
+
+ if (Tok.isNot(tok::r_paren)) {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "optimize";
+ return;
+ }
+ PP.Lex(Tok);
+
+ if (Tok.isNot(tok::eod)) {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+ << "optimize";
+ return;
+ }
+ PP.Diag(StartLoc, diag::warn_pragma_optimize);
+}
+
void PragmaForceCUDAHostDeviceHandler::HandlePragma(
Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) {
Token FirstTok = Tok;
@@ -2895,7 +3037,7 @@ void PragmaForceCUDAHostDeviceHandler::HandlePragma(
diag::warn_pragma_force_cuda_host_device_bad_arg);
}
-/// \brief Handle the #pragma clang attribute directive.
+/// Handle the #pragma clang attribute directive.
///
/// The syntax is:
/// \code
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 3f25610f4471..deb10af4b17b 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -12,13 +12,13 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/Attributes.h"
#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/LoopHint.h"
-#include "clang/Sema/PrettyDeclStackTrace.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/TypoCorrection.h"
using namespace clang;
@@ -27,7 +27,7 @@ using namespace clang;
// C99 6.8: Statements and Blocks.
//===----------------------------------------------------------------------===//
-/// \brief Parse a standalone statement (for instance, as the body of an 'if',
+/// Parse a standalone statement (for instance, as the body of an 'if',
/// 'while', or 'for').
StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc,
bool AllowOpenMPStandalone) {
@@ -116,7 +116,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
if (Attrs.empty() || Res.isInvalid())
return Res;
- return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range);
+ return Actions.ProcessStmtAttributes(Res.get(), Attrs, Attrs.Range);
}
namespace {
@@ -211,7 +211,7 @@ Retry:
Allowed == ACK_Any) &&
isDeclarationStatement()) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
- DeclGroupPtrTy Decl = ParseDeclaration(Declarator::BlockContext,
+ DeclGroupPtrTy Decl = ParseDeclaration(DeclaratorContext::BlockContext,
DeclEnd, Attrs);
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
}
@@ -402,7 +402,7 @@ Retry:
return Res;
}
-/// \brief Parse an expression statement.
+/// Parse an expression statement.
StmtResult Parser::ParseExprStatement() {
// If a case keyword is missing, this is where it should be inserted.
Token OldToken = Tok;
@@ -610,8 +610,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
Stmts, /*Allowed=*/ACK_StatementsOpenMPNonStandalone, nullptr,
TempAttrs);
if (!TempAttrs.empty() && !SubStmt.isInvalid())
- SubStmt = Actions.ProcessStmtAttributes(
- SubStmt.get(), TempAttrs.getList(), TempAttrs.Range);
+ SubStmt = Actions.ProcessStmtAttributes(SubStmt.get(), TempAttrs,
+ TempAttrs.Range);
} else {
Diag(Tok, diag::err_expected_after) << "__attribute__" << tok::semi;
}
@@ -627,10 +627,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
IdentTok.getLocation());
- if (AttributeList *Attrs = attrs.getList()) {
- Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
- attrs.clear();
- }
+ Actions.ProcessDeclAttributeList(Actions.CurScope, LD, attrs);
+ attrs.clear();
return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc,
SubStmt.get());
@@ -687,20 +685,12 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
ExprResult LHS;
if (!MissingCase) {
- LHS = ParseConstantExpression();
- if (!getLangOpts().CPlusPlus11) {
- LHS = Actions.CorrectDelayedTyposInExpr(LHS, [this](class Expr *E) {
- return Actions.VerifyIntegerConstantExpression(E);
- });
- }
+ LHS = ParseCaseExpression(CaseLoc);
if (LHS.isInvalid()) {
// If constant-expression is parsed unsuccessfully, recover by skipping
// current case statement (moving to the colon that ends it).
- if (SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch)) {
- TryConsumeToken(tok::colon, ColonLoc);
- continue;
- }
- return StmtError();
+ if (!SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch))
+ return StmtError();
}
} else {
LHS = Expr;
@@ -712,13 +702,10 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
ExprResult RHS;
if (TryConsumeToken(tok::ellipsis, DotDotDotLoc)) {
Diag(DotDotDotLoc, diag::ext_gnu_case_range);
- RHS = ParseConstantExpression();
+ RHS = ParseCaseExpression(CaseLoc);
if (RHS.isInvalid()) {
- if (SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch)) {
- TryConsumeToken(tok::colon, ColonLoc);
- continue;
- }
- return StmtError();
+ if (!SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch))
+ return StmtError();
}
}
@@ -740,8 +727,7 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
}
StmtResult Case =
- Actions.ActOnCaseStmt(CaseLoc, LHS.get(), DotDotDotLoc,
- RHS.get(), ColonLoc);
+ Actions.ActOnCaseStmt(CaseLoc, LHS, DotDotDotLoc, RHS, ColonLoc);
// If we had a sema error parsing this case, then just ignore it and
// continue parsing the sub-stmt.
@@ -954,7 +940,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
if (T.consumeOpen())
return StmtError();
- Sema::CompoundScopeRAII CompoundScope(Actions);
+ Sema::CompoundScopeRAII CompoundScope(Actions, isStmtExpr);
// Parse any pragmas at the beginning of the compound statement.
ParseCompoundStatementLeadingPragmas();
@@ -1021,8 +1007,8 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
ExtensionRAIIObject O(Diags);
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
- DeclGroupPtrTy Res = ParseDeclaration(Declarator::BlockContext, DeclEnd,
- attrs);
+ DeclGroupPtrTy Res =
+ ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, attrs);
R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
} else {
// Otherwise this was a unary __extension__ marker.
@@ -1196,7 +1182,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
{
EnterExpressionEvaluationContext PotentiallyDiscarded(
Actions, Sema::ExpressionEvaluationContext::DiscardedStatement, nullptr,
- false,
+ Sema::ExpressionEvaluationContextRecord::EK_Other,
/*ShouldEnter=*/ConstexprCondition && !*ConstexprCondition);
ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
}
@@ -1230,7 +1216,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
EnterExpressionEvaluationContext PotentiallyDiscarded(
Actions, Sema::ExpressionEvaluationContext::DiscardedStatement, nullptr,
- false,
+ Sema::ExpressionEvaluationContextRecord::EK_Other,
/*ShouldEnter=*/ConstexprCondition && *ConstexprCondition);
ElseStmt = ParseStatement();
@@ -1621,9 +1607,13 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
attrs, attrs.Range.getEnd());
ForRange = true;
} else if (isForInitDeclaration()) { // for (int X = 4;
+ ParenBraceBracketBalancer BalancerRAIIObj(*this);
+
// Parse declaration, which eats the ';'.
- if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode?
+ if (!C99orCXXorObjC) { // Use of C99-style for loops in C90 mode?
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
+ Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
+ }
// In C++0x, "for (T NS:a" might not be a typo for ::
bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
@@ -1631,7 +1621,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy DG = ParseSimpleDeclaration(
- Declarator::ForContext, DeclEnd, attrs, false,
+ DeclaratorContext::ForContext, DeclEnd, attrs, false,
MightBeForRangeStmt ? &ForRangeInit : nullptr);
FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
if (ForRangeInit.ParsedForRangeDecl()) {
@@ -1940,7 +1930,7 @@ StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
ArgsUnion(Hint.ValueExpr)};
TempAttrs.addNew(Hint.PragmaNameLoc->Ident, Hint.Range, nullptr,
Hint.PragmaNameLoc->Loc, ArgHints, 4,
- AttributeList::AS_Pragma);
+ ParsedAttr::AS_Pragma);
}
// Get the next statement.
@@ -1957,7 +1947,7 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
assert(Tok.is(tok::l_brace));
SourceLocation LBraceLoc = Tok.getLocation();
- PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc,
+ PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc,
"parsing function body");
// Save and reset current vtordisp stack if we have entered a C++ method body.
@@ -1990,7 +1980,7 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
assert(Tok.is(tok::kw_try) && "Expected 'try'");
SourceLocation TryLoc = ConsumeToken();
- PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, TryLoc,
+ PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc,
"parsing function try block");
// Constructor initializer list?
@@ -2181,7 +2171,7 @@ StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
if (ParseCXXTypeSpecifierSeq(DS))
return StmtError();
- Declarator ExDecl(DS, Declarator::CXXCatchContext);
+ Declarator ExDecl(DS, DeclaratorContext::CXXCatchContext);
ParseDeclarator(ExDecl);
ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl);
} else
@@ -2265,7 +2255,7 @@ bool Parser::ParseOpenCLUnrollHintAttribute(ParsedAttributes &Attrs) {
if (Attrs.empty())
return true;
- if (Attrs.getList()->getKind() != AttributeList::AT_OpenCLUnrollHint)
+ if (Attrs.begin()->getKind() != ParsedAttr::AT_OpenCLUnrollHint)
return true;
if (!(Tok.is(tok::kw_for) || Tok.is(tok::kw_while) || Tok.is(tok::kw_do))) {
diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp
index d81029e27974..290723c29532 100644
--- a/lib/Parse/ParseStmtAsm.cpp
+++ b/lib/Parse/ParseStmtAsm.cpp
@@ -239,7 +239,7 @@ ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
/*AllowDestructorName=*/false,
/*AllowConstructorName=*/false,
/*AllowDeductionGuide=*/false,
- /*ObjectType=*/nullptr, TemplateKWLoc, Id);
+ /*ObjectType=*/nullptr, &TemplateKWLoc, Id);
// Perform the lookup.
Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id,
IsUnevaluatedContext);
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 56a16b9e0271..f7a69c482e17 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -21,27 +21,22 @@
#include "clang/Sema/Scope.h"
using namespace clang;
-/// \brief Parse a template declaration, explicit instantiation, or
+/// Parse a template declaration, explicit instantiation, or
/// explicit specialization.
-Decl *
-Parser::ParseDeclarationStartingWithTemplate(unsigned Context,
- SourceLocation &DeclEnd,
- AccessSpecifier AS,
- AttributeList *AccessAttrs) {
+Decl *Parser::ParseDeclarationStartingWithTemplate(
+ DeclaratorContext Context, SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
ObjCDeclContextSwitch ObjCDC(*this);
if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) {
- return ParseExplicitInstantiation(Context,
- SourceLocation(), ConsumeToken(),
- DeclEnd, AS);
+ return ParseExplicitInstantiation(Context, SourceLocation(), ConsumeToken(),
+ DeclEnd, AccessAttrs, AS);
}
- return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS,
- AccessAttrs);
+ return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,
+ AS);
}
-
-
-/// \brief Parse a template declaration or an explicit specialization.
+/// Parse a template declaration or an explicit specialization.
///
/// Template declarations include one or more template parameter lists
/// and either the function or class template declaration. Explicit
@@ -56,11 +51,9 @@ Parser::ParseDeclarationStartingWithTemplate(unsigned Context,
///
/// explicit-specialization: [ C++ temp.expl.spec]
/// 'template' '<' '>' declaration
-Decl *
-Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
- SourceLocation &DeclEnd,
- AccessSpecifier AS,
- AttributeList *AccessAttrs) {
+Decl *Parser::ParseTemplateDeclarationOrSpecialization(
+ DeclaratorContext Context, SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
assert(Tok.isOneOf(tok::kw_export, tok::kw_template) &&
"Token does not start a template declaration.");
@@ -149,15 +142,13 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization);
// Parse the actual template declaration.
- return ParseSingleDeclarationAfterTemplate(Context,
- ParsedTemplateInfo(&ParamLists,
- isSpecialization,
- LastParamListWasEmpty),
- ParsingTemplateParams,
- DeclEnd, AS, AccessAttrs);
+ return ParseSingleDeclarationAfterTemplate(
+ Context,
+ ParsedTemplateInfo(&ParamLists, isSpecialization, LastParamListWasEmpty),
+ ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
}
-/// \brief Parse a single declaration that declares a template,
+/// Parse a single declaration that declares a template,
/// template specialization, or explicit instantiation of a template.
///
/// \param DeclEnd will receive the source location of the last token
@@ -167,14 +158,10 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
/// declaration. Will be AS_none for namespace-scope declarations.
///
/// \returns the new declaration.
-Decl *
-Parser::ParseSingleDeclarationAfterTemplate(
- unsigned Context,
- const ParsedTemplateInfo &TemplateInfo,
- ParsingDeclRAIIObject &DiagsFromTParams,
- SourceLocation &DeclEnd,
- AccessSpecifier AS,
- AttributeList *AccessAttrs) {
+Decl *Parser::ParseSingleDeclarationAfterTemplate(
+ DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
+ ParsingDeclRAIIObject &DiagsFromTParams, SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
"Template information required");
@@ -186,7 +173,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
return ParseStaticAssertDeclaration(DeclEnd);
}
- if (Context == Declarator::MemberContext) {
+ if (Context == DeclaratorContext::MemberContext) {
// We are parsing a member template.
ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
&DiagsFromTParams);
@@ -234,7 +221,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
DS.takeAttributesFrom(prefixAttrs);
// Parse the declarator.
- ParsingDeclarator DeclaratorInfo(*this, DS, (Declarator::TheContext)Context);
+ ParsingDeclarator DeclaratorInfo(*this, DS, (DeclaratorContext)Context);
ParseDeclarator(DeclaratorInfo);
// Error parsing the declarator?
if (!DeclaratorInfo.hasName()) {
@@ -255,7 +242,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
// Function definitions are only allowed at file scope and in C++ classes.
// The C++ inline method definition case is handled elsewhere, so we only
// need to handle the file scope definition case.
- if (Context != Declarator::FileContext) {
+ if (Context != DeclaratorContext::FileContext) {
Diag(Tok, diag::err_function_definition_not_allowed);
SkipMalformedDecl();
return nullptr;
@@ -271,7 +258,8 @@ Parser::ParseSingleDeclarationAfterTemplate(
}
if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
- if (DeclaratorInfo.getName().getKind() != UnqualifiedId::IK_TemplateId) {
+ if (DeclaratorInfo.getName().getKind() !=
+ UnqualifiedIdKind::IK_TemplateId) {
// If the declarator-id is not a template-id, issue a diagnostic and
// recover by ignoring the 'template' keyword.
Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
@@ -369,7 +357,7 @@ bool Parser::ParseTemplateParameters(
/// template-parameter
/// template-parameter-list ',' template-parameter
bool
-Parser::ParseTemplateParameterList(unsigned Depth,
+Parser::ParseTemplateParameterList(const unsigned Depth,
SmallVectorImpl<NamedDecl*> &TemplateParams) {
while (1) {
@@ -402,7 +390,7 @@ Parser::ParseTemplateParameterList(unsigned Depth,
return true;
}
-/// \brief Determine whether the parser is at the start of a template
+/// Determine whether the parser is at the start of a template
/// type parameter.
bool Parser::isStartOfTemplateTypeParameter() {
if (Tok.is(tok::kw_class)) {
@@ -487,6 +475,20 @@ NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
if (Tok.is(tok::kw_template))
return ParseTemplateTemplateParameter(Depth, Position);
+ // Is there just a typo in the input code? ('typedef' instead of 'typename')
+ if (Tok.is(tok::kw_typedef)) {
+ Diag(Tok.getLocation(), diag::err_expected_template_parameter);
+
+ Diag(Tok.getLocation(), diag::note_meant_to_use_typename)
+ << FixItHint::CreateReplacement(CharSourceRange::getCharRange(
+ Tok.getLocation(), Tok.getEndLoc()),
+ "typename");
+
+ Tok.setKind(tok::kw_typename);
+
+ return ParseTypeParameter(Depth, Position);
+ }
+
// If it's none of the above, then it must be a parameter declaration.
// NOTE: This will pick up errors in the closure of the template parameter
// list (e.g., template < ; Check here to implement >> style closures.
@@ -546,7 +548,7 @@ NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
ParsedType DefaultArg;
if (TryConsumeToken(tok::equal, EqualLoc))
DefaultArg = ParseTypeName(/*Range=*/nullptr,
- Declarator::TemplateTypeArgContext).get();
+ DeclaratorContext::TemplateTypeArgContext).get();
return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, EllipsisLoc,
KeyLoc, ParamName, NameLoc, Depth, Position,
@@ -676,10 +678,10 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
// declarators (parts of declarators?) are accepted for parameters.
DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
- DSC_template_param);
+ DeclSpecContext::DSC_template_param);
// Parse this as a typename.
- Declarator ParamDecl(DS, Declarator::TemplateParamContext);
+ Declarator ParamDecl(DS, DeclaratorContext::TemplateParamContext);
ParseDeclarator(ParamDecl);
if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
Diag(Tok.getLocation(), diag::err_expected_template_parameter);
@@ -739,7 +741,7 @@ void Parser::DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
AlreadyHasEllipsis, D.hasName());
}
-/// \brief Parses a '>' at the end of a template list.
+/// Parses a '>' at the end of a template list.
///
/// If this function encounters '>>', '>>>', '>=', or '>>=', it tries
/// to determine if these tokens were supposed to be a '>' followed by
@@ -760,6 +762,7 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
// What will be left once we've consumed the '>'.
tok::TokenKind RemainingToken;
const char *ReplacementStr = "> >";
+ bool MergeWithNextToken = false;
switch (Tok.getKind()) {
default:
@@ -785,6 +788,15 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
case tok::greaterequal:
RemainingToken = tok::equal;
ReplacementStr = "> =";
+
+ // Join two adjacent '=' tokens into one, for cases like:
+ // void (*p)() = f<int>;
+ // return f<int>==p;
+ if (NextToken().is(tok::equal) &&
+ areTokensAdjacent(Tok, NextToken())) {
+ RemainingToken = tok::equalequal;
+ MergeWithNextToken = true;
+ }
break;
case tok::greatergreaterequal:
@@ -792,22 +804,35 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
break;
}
- // This template-id is terminated by a token which starts with a '>'. Outside
- // C++11, this is now error recovery, and in C++11, this is error recovery if
- // the token isn't '>>' or '>>>'.
- // '>>>' is for CUDA, where this sequence of characters is parsed into
- // tok::greatergreatergreater, rather than two separate tokens.
+ // This template-id is terminated by a token that starts with a '>'.
+ // Outside C++11 and Objective-C, this is now error recovery.
+ //
+ // C++11 allows this when the token is '>>', and in CUDA + C++11 mode, we
+ // extend that treatment to also apply to the '>>>' token.
//
- // We always allow this for Objective-C type parameter and type argument
- // lists.
- RAngleLoc = Tok.getLocation();
+ // Objective-C allows this in its type parameter / argument lists.
+
+ SourceLocation TokBeforeGreaterLoc = PrevTokLocation;
+ SourceLocation TokLoc = Tok.getLocation();
Token Next = NextToken();
+
+ // Whether splitting the current token after the '>' would undesirably result
+ // in the remaining token pasting with the token after it. This excludes the
+ // MergeWithNextToken cases, which we've already handled.
+ bool PreventMergeWithNextToken =
+ (RemainingToken == tok::greater ||
+ RemainingToken == tok::greatergreater) &&
+ (Next.isOneOf(tok::greater, tok::greatergreater,
+ tok::greatergreatergreater, tok::equal, tok::greaterequal,
+ tok::greatergreaterequal, tok::equalequal)) &&
+ areTokensAdjacent(Tok, Next);
+
+ // Diagnose this situation as appropriate.
if (!ObjCGenericList) {
- // The source range of the '>>' or '>=' at the start of the token.
- CharSourceRange ReplacementRange =
- CharSourceRange::getCharRange(RAngleLoc,
- Lexer::AdvanceToTokenCharacter(RAngleLoc, 2, PP.getSourceManager(),
- getLangOpts()));
+ // The source range of the replaced token(s).
+ CharSourceRange ReplacementRange = CharSourceRange::getCharRange(
+ TokLoc, Lexer::AdvanceToTokenCharacter(TokLoc, 2, PP.getSourceManager(),
+ getLangOpts()));
// A hint to put a space between the '>>'s. In order to make the hint as
// clear as possible, we include the characters either side of the space in
@@ -818,13 +843,7 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
// A hint to put another space after the token, if it would otherwise be
// lexed differently.
FixItHint Hint2;
- if ((RemainingToken == tok::greater ||
- RemainingToken == tok::greatergreater) &&
- (Next.isOneOf(tok::greater, tok::greatergreater,
- tok::greatergreatergreater, tok::equal,
- tok::greaterequal, tok::greatergreaterequal,
- tok::equalequal)) &&
- areTokensAdjacent(Tok, Next))
+ if (PreventMergeWithNextToken)
Hint2 = FixItHint::CreateInsertion(Next.getLocation(), " ");
unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
@@ -833,55 +852,68 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
else if (Tok.is(tok::greaterequal))
DiagId = diag::err_right_angle_bracket_equal_needs_space;
- Diag(Tok.getLocation(), DiagId) << Hint1 << Hint2;
+ Diag(TokLoc, DiagId) << Hint1 << Hint2;
}
+ // Find the "length" of the resulting '>' token. This is not always 1, as it
+ // can contain escaped newlines.
+ unsigned GreaterLength = Lexer::getTokenPrefixLength(
+ TokLoc, 1, PP.getSourceManager(), getLangOpts());
+
+ // Annotate the source buffer to indicate that we split the token after the
+ // '>'. This allows us to properly find the end of, and extract the spelling
+ // of, the '>' token later.
+ RAngleLoc = PP.SplitToken(TokLoc, GreaterLength);
+
// Strip the initial '>' from the token.
- Token PrevTok = Tok;
- if (RemainingToken == tok::equal && Next.is(tok::equal) &&
- areTokensAdjacent(Tok, Next)) {
- // Join two adjacent '=' tokens into one, for cases like:
- // void (*p)() = f<int>;
- // return f<int>==p;
+ bool CachingTokens = PP.IsPreviousCachedToken(Tok);
+
+ Token Greater = Tok;
+ Greater.setLocation(RAngleLoc);
+ Greater.setKind(tok::greater);
+ Greater.setLength(GreaterLength);
+
+ unsigned OldLength = Tok.getLength();
+ if (MergeWithNextToken) {
ConsumeToken();
- Tok.setKind(tok::equalequal);
- Tok.setLength(Tok.getLength() + 1);
- } else {
- Tok.setKind(RemainingToken);
- Tok.setLength(Tok.getLength() - 1);
+ OldLength += Tok.getLength();
}
- Tok.setLocation(Lexer::AdvanceToTokenCharacter(RAngleLoc, 1,
- PP.getSourceManager(),
- getLangOpts()));
-
- // The advance from '>>' to '>' in a ObjectiveC template argument list needs
- // to be properly reflected in the token cache to allow correct interaction
- // between annotation and backtracking.
- if (ObjCGenericList && PrevTok.getKind() == tok::greatergreater &&
- RemainingToken == tok::greater && PP.IsPreviousCachedToken(PrevTok)) {
- PrevTok.setKind(RemainingToken);
- PrevTok.setLength(1);
- // Break tok::greatergreater into two tok::greater but only add the second
- // one in case the client asks to consume the last token.
+
+ Tok.setKind(RemainingToken);
+ Tok.setLength(OldLength - GreaterLength);
+
+ // Split the second token if lexing it normally would lex a different token
+ // (eg, the fifth token in 'A<B>>>' should re-lex as '>', not '>>').
+ SourceLocation AfterGreaterLoc = TokLoc.getLocWithOffset(GreaterLength);
+ if (PreventMergeWithNextToken)
+ AfterGreaterLoc = PP.SplitToken(AfterGreaterLoc, Tok.getLength());
+ Tok.setLocation(AfterGreaterLoc);
+
+ // Update the token cache to match what we just did if necessary.
+ if (CachingTokens) {
+ // If the previous cached token is being merged, delete it.
+ if (MergeWithNextToken)
+ PP.ReplacePreviousCachedToken({});
+
if (ConsumeLastToken)
- PP.ReplacePreviousCachedToken({PrevTok, Tok});
+ PP.ReplacePreviousCachedToken({Greater, Tok});
else
- PP.ReplacePreviousCachedToken({PrevTok});
+ PP.ReplacePreviousCachedToken({Greater});
}
- if (!ConsumeLastToken) {
- // Since we're not supposed to consume the '>' token, we need to push
- // this token and revert the current token back to the '>'.
+ if (ConsumeLastToken) {
+ PrevTokLocation = RAngleLoc;
+ } else {
+ PrevTokLocation = TokBeforeGreaterLoc;
PP.EnterToken(Tok);
- Tok.setKind(tok::greater);
- Tok.setLength(1);
- Tok.setLocation(RAngleLoc);
+ Tok = Greater;
}
+
return false;
}
-/// \brief Parses a template-id that after the template name has
+/// Parses a template-id that after the template name has
/// already been parsed.
///
/// This routine takes care of parsing the enclosed template argument
@@ -923,7 +955,7 @@ Parser::ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
/*ObjCGenericList=*/false);
}
-/// \brief Replace the tokens that form a simple-template-id with an
+/// Replace the tokens that form a simple-template-id with an
/// annotation token containing the complete template-id.
///
/// The first token in the stream must be the name of a template that
@@ -1015,12 +1047,12 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
Tok.setKind(tok::annot_template_id);
IdentifierInfo *TemplateII =
- TemplateName.getKind() == UnqualifiedId::IK_Identifier
+ TemplateName.getKind() == UnqualifiedIdKind::IK_Identifier
? TemplateName.Identifier
: nullptr;
OverloadedOperatorKind OpKind =
- TemplateName.getKind() == UnqualifiedId::IK_Identifier
+ TemplateName.getKind() == UnqualifiedIdKind::IK_Identifier
? OO_None
: TemplateName.OperatorFunctionId.Operator;
@@ -1044,7 +1076,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
return false;
}
-/// \brief Replaces a template-id annotation token with a type
+/// Replaces a template-id annotation token with a type
/// annotation token.
///
/// If there was a failure when forming the type from the template-id,
@@ -1089,12 +1121,12 @@ void Parser::AnnotateTemplateIdTokenAsType(bool IsClassName) {
PP.AnnotateCachedTokens(Tok);
}
-/// \brief Determine whether the given token can end a template argument.
+/// Determine whether the given token can end a template argument.
static bool isEndOfTemplateArgument(Token Tok) {
return Tok.isOneOf(tok::comma, tok::greater, tok::greatergreater);
}
-/// \brief Parse a C++ template template argument.
+/// Parse a C++ template template argument.
ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&
!Tok.is(tok::annot_cxxscope))
@@ -1190,17 +1222,13 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() {
// argument before trying to disambiguate.
EnterExpressionEvaluationContext EnterConstantEvaluated(
- Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+ Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated,
+ /*LambdaContextDecl=*/nullptr,
+ /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
if (isCXXTypeId(TypeIdAsTemplateArgument)) {
- SourceLocation Loc = Tok.getLocation();
- TypeResult TypeArg = ParseTypeName(/*Range=*/nullptr,
- Declarator::TemplateTypeArgContext);
- if (TypeArg.isInvalid())
- return ParsedTemplateArgument();
-
- return ParsedTemplateArgument(ParsedTemplateArgument::Type,
- TypeArg.get().getAsOpaquePtr(),
- Loc);
+ TypeResult TypeArg = ParseTypeName(
+ /*Range=*/nullptr, DeclaratorContext::TemplateArgContext);
+ return Actions.ActOnTemplateTypeArgument(TypeArg);
}
// Try to parse a template template argument.
@@ -1228,7 +1256,7 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() {
ExprArg.get(), Loc);
}
-/// \brief Determine whether the current tokens can only be parsed as a
+/// Determine whether the current tokens can only be parsed as a
/// template argument list (starting with the '<') and never as a '<'
/// expression.
bool Parser::IsTemplateArgumentList(unsigned Skip) {
@@ -1290,27 +1318,26 @@ Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
return false;
}
-/// \brief Parse a C++ explicit template instantiation
+/// Parse a C++ explicit template instantiation
/// (C++ [temp.explicit]).
///
/// explicit-instantiation:
/// 'extern' [opt] 'template' declaration
///
/// Note that the 'extern' is a GNU extension and C++11 feature.
-Decl *Parser::ParseExplicitInstantiation(unsigned Context,
+Decl *Parser::ParseExplicitInstantiation(DeclaratorContext Context,
SourceLocation ExternLoc,
SourceLocation TemplateLoc,
SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs,
AccessSpecifier AS) {
// This isn't really required here.
ParsingDeclRAIIObject
ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent);
- return ParseSingleDeclarationAfterTemplate(Context,
- ParsedTemplateInfo(ExternLoc,
- TemplateLoc),
- ParsingTemplateParams,
- DeclEnd, AS);
+ return ParseSingleDeclarationAfterTemplate(
+ Context, ParsedTemplateInfo(ExternLoc, TemplateLoc),
+ ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
}
SourceRange Parser::ParsedTemplateInfo::getSourceRange() const {
@@ -1328,7 +1355,7 @@ void Parser::LateTemplateParserCallback(void *P, LateParsedTemplate &LPT) {
((Parser *)P)->ParseLateTemplatedFuncDef(LPT);
}
-/// \brief Late parse a C++ function template in Microsoft mode.
+/// Late parse a C++ function template in Microsoft mode.
void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
if (!LPT.D)
return;
@@ -1419,7 +1446,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
delete *I;
}
-/// \brief Lex a delayed template function for late parsing.
+/// Lex a delayed template function for late parsing.
void Parser::LexTemplateFunctionForLateParsing(CachedTokens &Toks) {
tok::TokenKind kind = Tok.getKind();
if (!ConsumeAndStoreFunctionPrologue(Toks)) {
@@ -1435,3 +1462,111 @@ void Parser::LexTemplateFunctionForLateParsing(CachedTokens &Toks) {
}
}
}
+
+/// We've parsed something that could plausibly be intended to be a template
+/// name (\p LHS) followed by a '<' token, and the following code can't possibly
+/// be an expression. Determine if this is likely to be a template-id and if so,
+/// diagnose it.
+bool Parser::diagnoseUnknownTemplateId(ExprResult LHS, SourceLocation Less) {
+ TentativeParsingAction TPA(*this);
+ // FIXME: We could look at the token sequence in a lot more detail here.
+ if (SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
+ StopAtSemi | StopBeforeMatch)) {
+ TPA.Commit();
+
+ SourceLocation Greater;
+ ParseGreaterThanInTemplateList(Greater, true, false);
+ Actions.diagnoseExprIntendedAsTemplateName(getCurScope(), LHS,
+ Less, Greater);
+ return true;
+ }
+
+ // There's no matching '>' token, this probably isn't supposed to be
+ // interpreted as a template-id. Parse it as an (ill-formed) comparison.
+ TPA.Revert();
+ return false;
+}
+
+void Parser::checkPotentialAngleBracket(ExprResult &PotentialTemplateName) {
+ assert(Tok.is(tok::less) && "not at a potential angle bracket");
+
+ bool DependentTemplateName = false;
+ if (!Actions.mightBeIntendedToBeTemplateName(PotentialTemplateName,
+ DependentTemplateName))
+ return;
+
+ // OK, this might be a name that the user intended to be parsed as a
+ // template-name, followed by a '<' token. Check for some easy cases.
+
+ // If we have potential_template<>, then it's supposed to be a template-name.
+ if (NextToken().is(tok::greater) ||
+ (getLangOpts().CPlusPlus11 &&
+ NextToken().isOneOf(tok::greatergreater, tok::greatergreatergreater))) {
+ SourceLocation Less = ConsumeToken();
+ SourceLocation Greater;
+ ParseGreaterThanInTemplateList(Greater, true, false);
+ Actions.diagnoseExprIntendedAsTemplateName(
+ getCurScope(), PotentialTemplateName, Less, Greater);
+ // FIXME: Perform error recovery.
+ PotentialTemplateName = ExprError();
+ return;
+ }
+
+ // If we have 'potential_template<type-id', assume it's supposed to be a
+ // template-name if there's a matching '>' later on.
+ {
+ // FIXME: Avoid the tentative parse when NextToken() can't begin a type.
+ TentativeParsingAction TPA(*this);
+ SourceLocation Less = ConsumeToken();
+ if (isTypeIdUnambiguously() &&
+ diagnoseUnknownTemplateId(PotentialTemplateName, Less)) {
+ TPA.Commit();
+ // FIXME: Perform error recovery.
+ PotentialTemplateName = ExprError();
+ return;
+ }
+ TPA.Revert();
+ }
+
+ // Otherwise, remember that we saw this in case we see a potentially-matching
+ // '>' token later on.
+ AngleBracketTracker::Priority Priority =
+ (DependentTemplateName ? AngleBracketTracker::DependentName
+ : AngleBracketTracker::PotentialTypo) |
+ (Tok.hasLeadingSpace() ? AngleBracketTracker::SpaceBeforeLess
+ : AngleBracketTracker::NoSpaceBeforeLess);
+ AngleBrackets.add(*this, PotentialTemplateName.get(), Tok.getLocation(),
+ Priority);
+}
+
+bool Parser::checkPotentialAngleBracketDelimiter(
+ const AngleBracketTracker::Loc &LAngle, const Token &OpToken) {
+ // If a comma in an expression context is followed by a type that can be a
+ // template argument and cannot be an expression, then this is ill-formed,
+ // but might be intended to be part of a template-id.
+ if (OpToken.is(tok::comma) && isTypeIdUnambiguously() &&
+ diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
+ AngleBrackets.clear(*this);
+ return true;
+ }
+
+ // If a context that looks like a template-id is followed by '()', then
+ // this is ill-formed, but might be intended to be a template-id
+ // followed by '()'.
+ if (OpToken.is(tok::greater) && Tok.is(tok::l_paren) &&
+ NextToken().is(tok::r_paren)) {
+ Actions.diagnoseExprIntendedAsTemplateName(
+ getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
+ OpToken.getLocation());
+ AngleBrackets.clear(*this);
+ return true;
+ }
+
+ // After a '>' (etc), we're no longer potentially in a construct that's
+ // intended to be treated as a template-id.
+ if (OpToken.is(tok::greater) ||
+ (getLangOpts().CPlusPlus11 &&
+ OpToken.isOneOf(tok::greatergreater, tok::greatergreatergreater)))
+ AngleBrackets.clear(*this);
+ return false;
+}
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 5c206f4eab90..0603d8e75eea 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -401,7 +401,7 @@ struct Parser::ConditionDeclarationOrInitStatementState {
}
};
-/// \brief Disambiguates between a declaration in a condition, a
+/// Disambiguates between a declaration in a condition, a
/// simple-declaration in an init-statement, and an expression for
/// a condition of a if/switch statement.
///
@@ -472,7 +472,7 @@ Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement) {
return ConditionOrInitStatement::Expression;
}
- /// \brief Determine whether the next set of tokens contains a type-id.
+ /// Determine whether the next set of tokens contains a type-id.
///
/// The context parameter states what context we're parsing right
/// now, which affects how this routine copes with the token
@@ -553,7 +553,7 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
return TPR == TPResult::True;
}
-/// \brief Returns true if this is a C++11 attribute-specifier. Per
+/// Returns true if this is a C++11 attribute-specifier. Per
/// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens
/// always introduce an attribute. In Objective-C++11, this rule does not
/// apply if either '[' begins a message-send.
@@ -873,7 +873,8 @@ Parser::TPResult Parser::TryParseOperatorId() {
/// template-id [TODO]
///
Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
- bool mayHaveIdentifier) {
+ bool mayHaveIdentifier,
+ bool mayHaveDirectInit) {
// declarator:
// direct-declarator
// ptr-operator declarator
@@ -930,6 +931,9 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
return TPResult::False;
}
+ if (mayHaveDirectInit)
+ return TPResult::Ambiguous;
+
while (1) {
TPResult TPR(TPResult::Ambiguous);
@@ -1015,6 +1019,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
case tok::kw___FUNCDNAME__:
case tok::kw___FUNCSIG__:
case tok::kw_L__FUNCTION__:
+ case tok::kw_L__FUNCSIG__:
case tok::kw___PRETTY_FUNCTION__:
case tok::kw___uuidof:
#define TYPE_TRAIT(N,Spelling,K) \
@@ -1048,6 +1053,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
case tok::kw_class:
case tok::kw_typename:
case tok::kw_wchar_t:
+ case tok::kw_char8_t:
case tok::kw_char16_t:
case tok::kw_char32_t:
case tok::kw__Decimal32:
@@ -1242,6 +1248,17 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
case ANK_TentativeDecl:
return TPResult::False;
case ANK_TemplateName:
+ // In C++17, this could be a type template for class template argument
+ // deduction. Try to form a type annotation for it. If we're in a
+ // template template argument, we'll undo this when checking the
+ // validity of the argument.
+ if (getLangOpts().CPlusPlus17) {
+ if (TryAnnotateTypeOrScopeToken())
+ return TPResult::Error;
+ if (Tok.isNot(tok::identifier))
+ break;
+ }
+
// A bare type template-name which can't be a template template
// argument is an error, and was probably intended to be a type.
return GreaterThanIsOperator ? TPResult::True : TPResult::False;
@@ -1341,6 +1358,11 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
// cv-qualifier
case tok::kw_const:
case tok::kw_volatile:
+ case tok::kw___private:
+ case tok::kw___local:
+ case tok::kw___global:
+ case tok::kw___constant:
+ case tok::kw___generic:
// GNU
case tok::kw_restrict:
@@ -1420,8 +1442,6 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
*HasMissingTypename = true;
return TPResult::Ambiguous;
}
-
- // FIXME: Fails to either revert or commit the tentative parse!
} else {
// Try to resolve the name. If it doesn't exist, assume it was
// intended to name a type and keep disambiguating.
@@ -1431,19 +1451,33 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
case ANK_TentativeDecl:
return TPResult::False;
case ANK_TemplateName:
+ // In C++17, this could be a type template for class template
+ // argument deduction.
+ if (getLangOpts().CPlusPlus17) {
+ if (TryAnnotateTypeOrScopeToken())
+ return TPResult::Error;
+ if (Tok.isNot(tok::identifier))
+ break;
+ }
+
// A bare type template-name which can't be a template template
// argument is an error, and was probably intended to be a type.
- return GreaterThanIsOperator ? TPResult::True : TPResult::False;
+ // In C++17, this could be class template argument deduction.
+ return (getLangOpts().CPlusPlus17 || GreaterThanIsOperator)
+ ? TPResult::True
+ : TPResult::False;
case ANK_Unresolved:
return HasMissingTypename ? TPResult::Ambiguous
: TPResult::False;
case ANK_Success:
- // Annotated it, check again.
- assert(Tok.isNot(tok::annot_cxxscope) ||
- NextToken().isNot(tok::identifier));
- return isCXXDeclarationSpecifier(BracedCastResult,
- HasMissingTypename);
+ break;
}
+
+ // Annotated it, check again.
+ assert(Tok.isNot(tok::annot_cxxscope) ||
+ NextToken().isNot(tok::identifier));
+ return isCXXDeclarationSpecifier(BracedCastResult,
+ HasMissingTypename);
}
}
return TPResult::False;
@@ -1496,6 +1530,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
case tok::kw_char:
case tok::kw_wchar_t:
+ case tok::kw_char8_t:
case tok::kw_char16_t:
case tok::kw_char32_t:
case tok::kw_bool:
@@ -1587,6 +1622,7 @@ bool Parser::isCXXDeclarationSpecifierAType() {
// simple-type-specifier
case tok::kw_char:
case tok::kw_wchar_t:
+ case tok::kw_char8_t:
case tok::kw_char16_t:
case tok::kw_char32_t:
case tok::kw_bool:
@@ -1867,7 +1903,8 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() {
return TPResult::Error;
// cv-qualifier-seq
- while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict))
+ while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
+ tok::kw_restrict))
ConsumeToken();
// ref-qualifier[opt]
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 8aa50a2c7f2a..7a0b29cbae86 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -20,11 +20,12 @@
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
+#include "llvm/Support/Path.h"
using namespace clang;
namespace {
-/// \brief A comment handler that passes comments found by the preprocessor
+/// A comment handler that passes comments found by the preprocessor
/// to the parser action.
class ActionCommentHandler : public CommentHandler {
Sema &S;
@@ -77,7 +78,7 @@ DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) {
return Diag(Tok.getLocation(), DiagID);
}
-/// \brief Emits a diagnostic suggesting parentheses surrounding a
+/// Emits a diagnostic suggesting parentheses surrounding a
/// given range.
///
/// \param Loc The location where we'll emit the diagnostic.
@@ -697,9 +698,8 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
return nullptr;
case tok::semi:
// Either a C++11 empty-declaration or attribute-declaration.
- SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(),
- attrs.getList(),
- Tok.getLocation());
+ SingleDecl =
+ Actions.ActOnEmptyDeclaration(getCurScope(), attrs, Tok.getLocation());
ConsumeExtraSemi(OutsideFunction);
break;
case tok::r_brace:
@@ -741,7 +741,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
break;
}
case tok::at:
- return ParseObjCAtDirectives();
+ return ParseObjCAtDirectives(attrs);
case tok::minus:
case tok::plus:
if (!getLangOpts().ObjC1) {
@@ -783,7 +783,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
// A function definition cannot start with any of these keywords.
{
SourceLocation DeclEnd;
- return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs);
+ return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs);
}
case tok::kw_static:
@@ -793,7 +793,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
<< 0;
SourceLocation DeclEnd;
- return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs);
+ return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs);
}
goto dont_know;
@@ -804,7 +804,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
// Inline namespaces. Allowed as an extension even in C++03.
if (NextKind == tok::kw_namespace) {
SourceLocation DeclEnd;
- return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs);
+ return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs);
}
// Parse (then ignore) 'inline' prior to a template instantiation. This is
@@ -813,7 +813,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
<< 1;
SourceLocation DeclEnd;
- return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs);
+ return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs);
}
}
goto dont_know;
@@ -828,8 +828,8 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc);
SourceLocation DeclEnd;
return Actions.ConvertDeclToDeclGroup(
- ParseExplicitInstantiation(Declarator::FileContext,
- ExternLoc, TemplateLoc, DeclEnd));
+ ParseExplicitInstantiation(DeclaratorContext::FileContext, ExternLoc,
+ TemplateLoc, DeclEnd, attrs));
}
goto dont_know;
@@ -858,7 +858,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
return Actions.ConvertDeclToDeclGroup(SingleDecl);
}
-/// \brief Determine whether the current token, if it occurs after a
+/// Determine whether the current token, if it occurs after a
/// declarator, continues a declaration or declaration list.
bool Parser::isDeclarationAfterDeclarator() {
// Check for '= delete' or '= default'
@@ -877,7 +877,7 @@ bool Parser::isDeclarationAfterDeclarator() {
Tok.is(tok::l_paren)); // int X(0) -> not a function def [C++]
}
-/// \brief Determine whether the current token, if it occurs after a
+/// Determine whether the current token, if it occurs after a
/// declarator, indicates the start of a function definition.
bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
assert(Declarator.isFunctionDeclarator() && "Isn't a function declarator");
@@ -919,12 +919,13 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
AccessSpecifier AS) {
MaybeParseMicrosoftAttributes(DS.getAttributes());
// Parse the common declaration-specifiers piece.
- ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
+ ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS,
+ DeclSpecContext::DSC_top_level);
// If we had a free-standing type definition with a missing semicolon, we
// may get this far before the problem becomes obvious.
- if (DS.hasTagDefinition() &&
- DiagnoseMissingSemiAfterTagDefinition(DS, AS, DSC_top_level))
+ if (DS.hasTagDefinition() && DiagnoseMissingSemiAfterTagDefinition(
+ DS, AS, DeclSpecContext::DSC_top_level))
return nullptr;
// C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
@@ -1004,11 +1005,11 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
if (getLangOpts().CPlusPlus && isTokenStringLiteral() &&
DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
- Decl *TheDecl = ParseLinkage(DS, Declarator::FileContext);
+ Decl *TheDecl = ParseLinkage(DS, DeclaratorContext::FileContext);
return Actions.ConvertDeclToDeclGroup(TheDecl);
}
- return ParseDeclGroup(DS, Declarator::FileContext);
+ return ParseDeclGroup(DS, DeclaratorContext::FileContext);
}
Parser::DeclGroupPtrTy
@@ -1088,15 +1089,10 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// Check to make sure that any normal attributes are allowed to be on
// a definition. Late parsed attributes are checked at the end.
if (Tok.isNot(tok::equal)) {
- AttributeList *DtorAttrs = D.getAttributes();
- while (DtorAttrs) {
- if (DtorAttrs->isKnownToGCC() &&
- !DtorAttrs->isCXX11Attribute()) {
- Diag(DtorAttrs->getLoc(), diag::warn_attribute_on_function_definition)
- << DtorAttrs->getName();
- }
- DtorAttrs = DtorAttrs->getNext();
- }
+ for (const ParsedAttr &AL : D.getAttributes())
+ if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
+ Diag(AL.getLoc(), diag::warn_attribute_on_function_definition)
+ << AL.getName();
}
// In delayed template parsing mode, for function template we consume the
@@ -1313,7 +1309,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
}
// Parse the first declarator attached to this declspec.
- Declarator ParmDeclarator(DS, Declarator::KNRTypeListContext);
+ Declarator ParmDeclarator(DS, DeclaratorContext::KNRTypeListContext);
ParseDeclarator(ParmDeclarator);
// Handle the full declarator list.
@@ -1450,7 +1446,7 @@ ExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) {
return Result;
}
-/// \brief Get the TemplateIdAnnotation from the token and put it in the
+/// Get the TemplateIdAnnotation from the token and put it in the
/// cleanup pool so that it gets destroyed when parsing the current top level
/// declaration is finished.
TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) {
@@ -1478,7 +1474,7 @@ void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) {
PP.AnnotateCachedTokens(Tok);
}
-/// \brief Attempt to classify the name at the current token position. This may
+/// Attempt to classify the name at the current token position. This may
/// form a type, scope or primary expression annotation, or replace the token
/// with a typo-corrected keyword. This is only appropriate when the current
/// name must refer to an entity which has already been declared.
@@ -1763,7 +1759,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() {
return TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation);
}
-/// \brief Try to annotate a type or scope token, having already parsed an
+/// Try to annotate a type or scope token, having already parsed an
/// optional scope specifier. \p IsNewScope should be \c true unless the scope
/// specifier was extracted from an existing tok::annot_cxxscope annotation.
bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS,
@@ -1774,8 +1770,8 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS,
*Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), &SS,
false, NextToken().is(tok::period), nullptr,
/*IsCtorOrDtorName=*/false,
- /*NonTrivialTypeSourceInfo*/ true,
- /*IsClassTemplateDeductionContext*/GreaterThanIsOperator)) {
+ /*NonTrivialTypeSourceInfo*/true,
+ /*IsClassTemplateDeductionContext*/true)) {
SourceLocation BeginLoc = Tok.getLocation();
if (SS.isNotEmpty()) // it was a C++ qualified type name.
BeginLoc = SS.getBeginLoc();
@@ -2001,7 +1997,7 @@ bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) {
if (ParseUnqualifiedId(
Result.SS, /*EnteringContext*/false, /*AllowDestructorName*/true,
/*AllowConstructorName*/true, /*AllowDeductionGuide*/false, nullptr,
- TemplateKWLoc, Result.Name)) {
+ &TemplateKWLoc, Result.Name)) {
T.skipToEnd();
return true;
}
@@ -2122,6 +2118,7 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc) {
assert((AtLoc.isInvalid() ? Tok.is(tok::kw_import)
: Tok.isObjCAtKeyword(tok::objc_import)) &&
"Improper start to module import");
+ bool IsObjCAtImport = Tok.isObjCAtKeyword(tok::objc_import);
SourceLocation ImportLoc = ConsumeToken();
SourceLocation StartLoc = AtLoc.isInvalid() ? ImportLoc : AtLoc;
@@ -2145,6 +2142,16 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc) {
if (Import.isInvalid())
return nullptr;
+ // Using '@import' in framework headers requires modules to be enabled so that
+ // the header is parseable. Emit a warning to make the user aware.
+ if (IsObjCAtImport && AtLoc.isValid()) {
+ auto &SrcMgr = PP.getSourceManager();
+ auto *FE = SrcMgr.getFileEntryForID(SrcMgr.getFileID(AtLoc));
+ if (FE && llvm::sys::path::parent_path(FE->getDir()->getName())
+ .endswith(".framework"))
+ Diags.Report(AtLoc, diag::warn_atimport_in_framework_header);
+ }
+
return Import.get();
}
@@ -2184,7 +2191,7 @@ bool Parser::ParseModuleName(
}
}
-/// \brief Try recover parser when module annotation appears where it must not
+/// Try recover parser when module annotation appears where it must not
/// be found.
/// \returns false if the recover was successful and parsing may be continued, or
/// true if parser must bail out to top level and handle the token there.
@@ -2249,7 +2256,7 @@ bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
return true;
}
- if (getDepth() < MaxDepth)
+ if (getDepth() < P.getLangOpts().BracketDepth)
return false;
return diagnoseOverflow();