summaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r--lib/Parse/ParseDecl.cpp249
1 files changed, 160 insertions, 89 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index c64b97d01b9a..45e1c3e465ce 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -28,6 +28,7 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ScopedPrinter.h"
using namespace clang;
@@ -609,7 +610,6 @@ void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
case tok::kw___ptr64:
case tok::kw___w64:
case tok::kw___ptr32:
- case tok::kw___unaligned:
case tok::kw___sptr:
case tok::kw___uptr: {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
@@ -670,7 +670,7 @@ void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
}
}
-void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) {
+void Parser::ParseOpenCLKernelAttributes(ParsedAttributes &attrs) {
// Treat these like attributes
while (Tok.is(tok::kw___kernel)) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
@@ -720,7 +720,7 @@ static bool VersionNumberSeparator(const char Separator) {
/// simple-integer ',' simple-integer
/// simple-integer ',' simple-integer ',' simple-integer
VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
- Range = Tok.getLocation();
+ Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
if (!Tok.is(tok::numeric_constant)) {
Diag(Tok, diag::err_expected_version);
@@ -833,11 +833,15 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
/// \brief Parse the contents of the "availability" attribute.
///
/// availability-attribute:
-/// 'availability' '(' platform ',' version-arg-list, opt-message')'
+/// 'availability' '(' platform ',' opt-strict version-arg-list,
+/// opt-replacement, opt-message')'
///
/// platform:
/// identifier
///
+/// opt-strict:
+/// 'strict' ','
+///
/// version-arg-list:
/// version-arg
/// version-arg ',' version-arg-list
@@ -847,6 +851,8 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
/// 'deprecated' '=' version
/// 'obsoleted' = version
/// 'unavailable'
+/// opt-replacement:
+/// 'replacement' '=' <string>
/// opt-message:
/// 'message' '=' <string>
void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
@@ -858,7 +864,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
AttributeList::Syntax Syntax) {
enum { Introduced, Deprecated, Obsoleted, Unknown };
AvailabilityChange Changes[Unknown];
- ExprResult MessageExpr;
+ ExprResult MessageExpr, ReplacementExpr;
// Opening '('.
BalancedDelimiterTracker T(*this, tok::l_paren);
@@ -867,13 +873,20 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
return;
}
- // Parse the platform name,
+ // Parse the platform name.
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_availability_expected_platform);
SkipUntil(tok::r_paren, StopAtSemi);
return;
}
IdentifierLoc *Platform = ParseIdentifierLoc();
+ // Canonicalize platform name from "macosx" to "macos".
+ if (Platform->Ident && Platform->Ident->getName() == "macosx")
+ Platform->Ident = PP.getIdentifierInfo("macos");
+ // Canonicalize platform name from "macosx_app_extension" to
+ // "macos_app_extension".
+ if (Platform->Ident && Platform->Ident->getName() == "macosx_app_extension")
+ Platform->Ident = PP.getIdentifierInfo("macos_app_extension");
// Parse the ',' following the platform name.
if (ExpectAndConsume(tok::comma)) {
@@ -889,10 +902,13 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
Ident_obsoleted = PP.getIdentifierInfo("obsoleted");
Ident_unavailable = PP.getIdentifierInfo("unavailable");
Ident_message = PP.getIdentifierInfo("message");
+ Ident_strict = PP.getIdentifierInfo("strict");
+ Ident_replacement = PP.getIdentifierInfo("replacement");
}
- // Parse the set of introductions/deprecations/removals.
- SourceLocation UnavailableLoc;
+ // Parse the optional "strict", the optional "replacement" and the set of
+ // introductions/deprecations/removals.
+ SourceLocation UnavailableLoc, StrictLoc;
do {
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_availability_expected_change);
@@ -902,6 +918,15 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
IdentifierInfo *Keyword = Tok.getIdentifierInfo();
SourceLocation KeywordLoc = ConsumeToken();
+ if (Keyword == Ident_strict) {
+ if (StrictLoc.isValid()) {
+ Diag(KeywordLoc, diag::err_availability_redundant)
+ << Keyword << SourceRange(StrictLoc);
+ }
+ StrictLoc = KeywordLoc;
+ continue;
+ }
+
if (Keyword == Ident_unavailable) {
if (UnavailableLoc.isValid()) {
Diag(KeywordLoc, diag::err_availability_redundant)
@@ -917,14 +942,17 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
return;
}
ConsumeToken();
- if (Keyword == Ident_message) {
+ if (Keyword == Ident_message || Keyword == Ident_replacement) {
if (Tok.isNot(tok::string_literal)) {
Diag(Tok, diag::err_expected_string_literal)
<< /*Source='availability attribute'*/2;
SkipUntil(tok::r_paren, StopAtSemi);
return;
}
- MessageExpr = ParseStringLiteralExpression();
+ if (Keyword == Ident_message)
+ MessageExpr = ParseStringLiteralExpression();
+ else
+ ReplacementExpr = ParseStringLiteralExpression();
// Also reject wide string literals.
if (StringLiteral *MessageStringLiteral =
cast_or_null<StringLiteral>(MessageExpr.get())) {
@@ -936,7 +964,10 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
return;
}
}
- break;
+ if (Keyword == Ident_message)
+ break;
+ else
+ continue;
}
// Special handling of 'NA' only when applied to introduced or
@@ -1023,7 +1054,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
Changes[Deprecated],
Changes[Obsoleted],
UnavailableLoc, MessageExpr.get(),
- Syntax);
+ Syntax, StrictLoc, ReplacementExpr.get());
}
/// \brief Parse the contents of the "objc_bridge_related" attribute.
@@ -1187,7 +1218,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
// Append the current token at the end of the new token stream so that it
// doesn't get lost.
LA.Toks.push_back(Tok);
- PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false);
+ PP.EnterTokenStream(LA.Toks, true);
// Consume the previously pushed token.
ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
@@ -1402,8 +1433,8 @@ void Parser::handleDeclspecAlignBeforeClassKey(ParsedAttributesWithRange &Attrs,
while (AL) {
AttributeList *Next = AL->getNext();
- // We only consider attributes using the appropriate '__declspec' spelling,
- // this behavior doesn't extend to any other spellings.
+ // We only consider attributes using the appropriate '__declspec' spelling.
+ // This behavior doesn't extend to any other spellings.
if (AL->getKind() == AttributeList::AT_Aligned &&
AL->isDeclspecAttribute()) {
// Stitch the attribute into the tag's attribute list.
@@ -1522,7 +1553,7 @@ Parser::ParseSimpleDeclaration(unsigned Context,
// may get this far before the problem becomes obvious.
if (DS.hasTagDefinition() &&
DiagnoseMissingSemiAfterTagDefinition(DS, AS_none, DSContext))
- return DeclGroupPtrTy();
+ return nullptr;
// C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
// declaration-specifiers init-declarator-list[opt] ';'
@@ -1530,9 +1561,14 @@ Parser::ParseSimpleDeclaration(unsigned Context,
ProhibitAttributes(Attrs);
DeclEnd = Tok.getLocation();
if (RequireSemi) ConsumeToken();
+ RecordDecl *AnonRecord = nullptr;
Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
- DS);
+ DS, AnonRecord);
DS.complete(TheDecl);
+ if (AnonRecord) {
+ Decl* decls[] = {AnonRecord, TheDecl};
+ return Actions.BuildDeclaratorGroup(decls, /*TypeMayContainAuto=*/false);
+ }
return Actions.ConvertDeclToDeclGroup(TheDecl);
}
@@ -1701,7 +1737,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// Bail out if the first declarator didn't seem well-formed.
if (!D.hasName() && !D.mayOmitIdentifier()) {
SkipMalformedDecl();
- return DeclGroupPtrTy();
+ return nullptr;
}
// Save late-parsed attributes for now; they need to be parsed in the
@@ -1766,19 +1802,19 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
} else {
Diag(Tok, diag::err_expected_fn_body);
SkipUntil(tok::semi);
- return DeclGroupPtrTy();
+ return nullptr;
}
} else {
if (Tok.is(tok::l_brace)) {
Diag(Tok, diag::err_function_definition_not_allowed);
SkipMalformedDecl();
- return DeclGroupPtrTy();
+ return nullptr;
}
}
}
if (ParseAsmAttributesAfterDeclarator(D))
- return DeclGroupPtrTy();
+ return nullptr;
// C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
// must parse and analyze the for-range-initializer before the declaration is
@@ -1975,7 +2011,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
TemplateParameterLists FakedParamLists;
FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None,
- LAngleLoc));
+ LAngleLoc, nullptr));
ThisDecl =
Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
@@ -2039,7 +2075,8 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
if (Init.isInvalid()) {
SmallVector<tok::TokenKind, 2> StopTokens;
StopTokens.push_back(tok::comma);
- if (D.getContext() == Declarator::ForContext)
+ if (D.getContext() == Declarator::ForContext ||
+ D.getContext() == Declarator::InitStmtContext)
StopTokens.push_back(tok::r_paren);
SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
Actions.ActOnInitializerError(ThisDecl);
@@ -2250,6 +2287,24 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
return false;
}
+ if (getLangOpts().CPlusPlus && (!SS || SS->isEmpty()) &&
+ getLangOpts().MSVCCompat) {
+ // Lookup of an unqualified type name has failed in MSVC compatibility mode.
+ // Give Sema a chance to recover if we are in a template with dependent base
+ // classes.
+ if (ParsedType T = Actions.ActOnMSVCUnknownTypeName(
+ *Tok.getIdentifierInfo(), Tok.getLocation(),
+ DSC == DSC_template_type_arg)) {
+ const char *PrevSpec;
+ unsigned DiagID;
+ DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T,
+ Actions.getASTContext().getPrintingPolicy());
+ DS.SetRangeEnd(Tok.getLocation());
+ ConsumeToken();
+ return false;
+ }
+ }
+
// Otherwise, if we don't consume this token, we are going to emit an
// error anyway. Try to recover from various common problems. Check
// to see if this was a reference to a tag name without a tag specified.
@@ -2632,7 +2687,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
bool AttrsLastTime = false;
ParsedAttributesWithRange attrs(AttrFactory);
// We use Sema's policy to get bool macros right.
- const PrintingPolicy &Policy = Actions.getPrintingPolicy();
+ PrintingPolicy Policy = Actions.getPrintingPolicy();
while (1) {
bool isInvalid = false;
bool isStorageClass = false;
@@ -2835,12 +2890,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
<< Next.getIdentifierInfo() << 1 /* type */;
}
- ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
- Next.getLocation(),
- getCurScope(), &SS,
- false, false, ParsedType(),
- /*IsCtorOrDtorName=*/false,
- /*NonTrivialSourceInfo=*/true);
+ ParsedType TypeRep =
+ Actions.getTypeName(*Next.getIdentifierInfo(), Next.getLocation(),
+ getCurScope(), &SS, false, false, nullptr,
+ /*IsCtorOrDtorName=*/false,
+ /*NonTrivialSourceInfo=*/true);
// If the referenced identifier is not a type, then this declspec is
// erroneous: We already checked about that it has no type specifier, and
@@ -2958,16 +3012,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Actions.getTypeName(*Tok.getIdentifierInfo(),
Tok.getLocation(), getCurScope());
- // MSVC: If we weren't able to parse a default template argument, and it's
- // just a simple identifier, create a DependentNameType. This will allow
- // us to defer the name lookup to template instantiation time, as long we
- // forge a NestedNameSpecifier for the current context.
- if (!TypeRep && DSContext == DSC_template_type_arg &&
- getLangOpts().MSVCCompat && getCurScope()->isTemplateParamScope()) {
- TypeRep = Actions.ActOnDelayedDefaultTemplateArg(
- *Tok.getIdentifierInfo(), Tok.getLocation());
- }
-
// If this is not a typedef name, don't parse it as part of the declspec,
// it must be an implicit int or an error.
if (!TypeRep) {
@@ -3059,6 +3103,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
break;
}
+ case tok::kw___unaligned:
+ isInvalid = DS.SetTypeQual(DeclSpec::TQ_unaligned, Loc, PrevSpec, DiagID,
+ getLangOpts());
+ break;
+
case tok::kw___sptr:
case tok::kw___uptr:
case tok::kw___ptr64:
@@ -3069,7 +3118,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
case tok::kw___fastcall:
case tok::kw___thiscall:
case tok::kw___vectorcall:
- case tok::kw___unaligned:
ParseMicrosoftTypeAttributes(DS.getAttributes());
continue;
@@ -3080,7 +3128,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// OpenCL single token adornments.
case tok::kw___kernel:
- ParseOpenCLAttributes(DS.getAttributes());
+ ParseOpenCLKernelAttributes(DS.getAttributes());
continue;
// Nullability type specifiers.
@@ -3278,6 +3326,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
DiagID, Policy);
break;
+ case tok::kw___float128:
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec,
+ DiagID, Policy);
+ break;
case tok::kw_wchar_t:
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
DiagID, Policy);
@@ -3335,6 +3387,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
}
isInvalid = DS.SetTypePipe(true, Loc, PrevSpec, DiagID, Policy);
break;
+#define GENERIC_IMAGE_TYPE(ImgType, Id) \
+ case tok::kw_##ImgType##_t: \
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, \
+ DiagID, Policy); \
+ break;
+#include "clang/Basic/OpenCLImageTypes.def"
case tok::kw___unknown_anytype:
isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
PrevSpec, DiagID, Policy);
@@ -3403,6 +3461,22 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
ParseDecltypeSpecifier(DS);
continue;
+ case tok::annot_pragma_pack:
+ HandlePragmaPack();
+ continue;
+
+ case tok::annot_pragma_ms_pragma:
+ HandlePragmaMSPragma();
+ continue;
+
+ case tok::annot_pragma_ms_vtordisp:
+ HandlePragmaMSVtorDisp();
+ continue;
+
+ case tok::annot_pragma_ms_pointers_to_members:
+ HandlePragmaMSPointersToMembers();
+ continue;
+
case tok::kw___underlying_type:
ParseUnderlyingTypeSpecifier(DS);
continue;
@@ -3473,9 +3547,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
if (DiagID == diag::ext_duplicate_declspec)
Diag(Tok, DiagID)
<< PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
- else if (DiagID == diag::err_opencl_unknown_type_specifier)
- Diag(Tok, DiagID) << PrevSpec << isStorageClass;
- else
+ 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;
+ } else
Diag(Tok, DiagID) << PrevSpec;
}
@@ -3521,8 +3599,10 @@ void Parser::ParseStructDeclaration(
// If there are no declarators, this is a free-standing declaration
// specifier. Let the actions module cope with it.
if (Tok.is(tok::semi)) {
+ RecordDecl *AnonRecord = nullptr;
Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
- DS);
+ DS, AnonRecord);
+ assert(!AnonRecord && "Did not expect anonymous struct or union here");
DS.complete(TheDecl);
return;
}
@@ -3625,12 +3705,12 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
if (Tok.is(tok::annot_pragma_openmp)) {
// Result can be ignored, because it must be always empty.
- auto Res = ParseOpenMPDeclarativeDirective();
- assert(!Res);
- // Silence possible warnings.
- (void)Res;
+ AccessSpecifier AS = AS_none;
+ ParsedAttributesWithRange Attrs(AttrFactory);
+ (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
continue;
}
+
if (!Tok.is(tok::at)) {
auto CFieldCallback = [&](ParsingFieldDeclarator &FD) {
// Install the declarator into the current TagDecl.
@@ -3693,8 +3773,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
T.getOpenLocation(), T.getCloseLocation(),
attrs.getList());
StructScope.Exit();
- Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
- T.getCloseLocation());
+ Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange());
}
/// ParseEnumSpecifier
@@ -3788,7 +3867,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
CXXScopeSpec Spec;
- if (ParseOptionalCXXScopeSpecifier(Spec, ParsedType(),
+ if (ParseOptionalCXXScopeSpecifier(Spec, nullptr,
/*EnteringContext=*/true))
return;
@@ -4189,7 +4268,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
ParsedAttributes attrs(AttrFactory);
MaybeParseGNUAttributes(attrs);
- Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(),
+ Actions.ActOnEnumBody(StartLoc, T.getRange(),
EnumDecl, EnumConstantDecls,
getCurScope(),
attrs.getList());
@@ -4203,8 +4282,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
}
EnumScope.Exit();
- Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
- T.getCloseLocation());
+ Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, T.getRange());
// The next token must be valid after an enum definition. If not, a ';'
// was probably forgotten.
@@ -4219,27 +4297,6 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
}
}
-/// isTypeSpecifierQualifier - Return true if the current token could be the
-/// start of a type-qualifier-list.
-bool Parser::isTypeQualifier() const {
- switch (Tok.getKind()) {
- default: return false;
- // type-qualifier
- case tok::kw_const:
- case tok::kw_volatile:
- case tok::kw_restrict:
- case tok::kw___private:
- case tok::kw___local:
- case tok::kw___global:
- case tok::kw___constant:
- case tok::kw___generic:
- case tok::kw___read_only:
- case tok::kw___read_write:
- case tok::kw___write_only:
- return true;
- }
-}
-
/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
/// is definitely a type-specifier. Return false if it isn't part of a type
/// specifier or if we're not sure.
@@ -4264,12 +4321,15 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
+ case tok::kw___float128:
case tok::kw_bool:
case tok::kw__Bool:
case tok::kw__Decimal32:
case tok::kw__Decimal64:
case tok::kw__Decimal128:
case tok::kw___vector:
+#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
+#include "clang/Basic/OpenCLImageTypes.def"
// struct-or-union-specifier (C99) or class-specifier (C++)
case tok::kw_class:
@@ -4336,12 +4396,15 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
+ case tok::kw___float128:
case tok::kw_bool:
case tok::kw__Bool:
case tok::kw__Decimal32:
case tok::kw__Decimal64:
case tok::kw__Decimal128:
case tok::kw___vector:
+#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
+#include "clang/Basic/OpenCLImageTypes.def"
// struct-or-union-specifier (C99) or class-specifier (C++)
case tok::kw_class:
@@ -4488,6 +4551,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
+ case tok::kw___float128:
case tok::kw_bool:
case tok::kw__Bool:
case tok::kw__Decimal32:
@@ -4578,6 +4642,8 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
case tok::kw___read_only:
case tok::kw___read_write:
case tok::kw___write_only:
+#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
+#include "clang/Basic/OpenCLImageTypes.def"
return true;
}
@@ -4588,7 +4654,7 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified) {
// Parse the C++ scope specifier.
CXXScopeSpec SS;
- if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
+ if (ParseOptionalCXXScopeSpecifier(SS, nullptr,
/*EnteringContext=*/true)) {
TPA.Revert();
return false;
@@ -4770,6 +4836,10 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs,
ParseOpenCLQualifiers(DS.getAttributes());
break;
+ case tok::kw___unaligned:
+ isInvalid = DS.SetTypeQual(DeclSpec::TQ_unaligned, Loc, PrevSpec, DiagID,
+ getLangOpts());
+ break;
case tok::kw___uptr:
// GNU libc headers in C mode use '__uptr' as an identifer which conflicts
// with the MS modifier keyword.
@@ -4787,7 +4857,6 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs,
case tok::kw___fastcall:
case tok::kw___thiscall:
case tok::kw___vectorcall:
- case tok::kw___unaligned:
if (AttrReqs & AR_DeclspecAttributesParsed) {
ParseMicrosoftTypeAttributes(DS.getAttributes());
continue;
@@ -4925,14 +4994,14 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
// Member pointers get special handling, since there's no place for the
// scope spec in the generic path below.
if (getLangOpts().CPlusPlus &&
- (Tok.is(tok::coloncolon) ||
+ (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
(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;
CXXScopeSpec SS;
- ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext);
+ ParseOptionalCXXScopeSpecifier(SS, nullptr, EnteringContext);
if (SS.isNotEmpty()) {
if (Tok.isNot(tok::star)) {
@@ -4969,7 +5038,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
tok::TokenKind Kind = Tok.getKind();
if (D.getDeclSpec().isTypeSpecPipe() && !isPipeDeclerator(D)) {
- DeclSpec &DS = D.getMutableDeclSpec();
+ DeclSpec DS(AttrFactory);
+ ParseTypeQualifierListOpt(DS);
D.AddTypeInfo(
DeclaratorChunk::getPipe(DS.getTypeQualifiers(), DS.getPipeLoc()),
@@ -5009,7 +5079,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
DS.getConstSpecLoc(),
DS.getVolatileSpecLoc(),
DS.getRestrictSpecLoc(),
- DS.getAtomicSpecLoc()),
+ DS.getAtomicSpecLoc(),
+ DS.getUnalignedSpecLoc()),
DS.getAttributes(),
SourceLocation());
else
@@ -5147,7 +5218,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
if (D.getCXXScopeSpec().isEmpty()) {
bool EnteringContext = D.getContext() == Declarator::FileContext ||
D.getContext() == Declarator::MemberContext;
- ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(),
+ ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), nullptr,
EnteringContext);
}
@@ -5208,11 +5279,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
bool HadScope = D.getCXXScopeSpec().isValid();
if (ParseUnqualifiedId(D.getCXXScopeSpec(),
/*EnteringContext=*/true,
- /*AllowDestructorName=*/true,
- AllowConstructorName,
- ParsedType(),
- TemplateKWLoc,
- D.getName()) ||
+ /*AllowDestructorName=*/true, AllowConstructorName,
+ nullptr, TemplateKWLoc, D.getName()) ||
// Once we're past the identifier, if the scope was bad, mark the
// whole declarator bad.
D.getCXXScopeSpec().isInvalid()) {
@@ -6013,6 +6081,9 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
T.getCloseLocation()),
attrs, T.getCloseLocation());
return;
+ } else if (Tok.getKind() == tok::code_completion) {
+ Actions.CodeCompleteBracketDeclarator(getCurScope());
+ return cutOffParsing();
}
// If valid, this location is the position where we read the 'static' keyword.