summaryrefslogtreecommitdiffstats
path: root/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r--lib/Parse/ParseDeclCXX.cpp64
1 files changed, 46 insertions, 18 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index f8359f1e87..c4fe23c60c 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -1,9 +1,8 @@
//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -25,6 +24,7 @@
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/TimeProfiler.h"
using namespace clang;
@@ -437,9 +437,10 @@ Decl *Parser::ParseExportDeclaration() {
// The Modules TS draft says "An export-declaration shall declare at least one
// entity", but the intent is that it shall contain at least one declaration.
- if (Tok.is(tok::r_brace))
+ if (Tok.is(tok::r_brace) && getLangOpts().ModulesTS) {
Diag(ExportLoc, diag::err_export_empty)
<< SourceRange(ExportLoc, Tok.getLocation());
+ }
while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
Tok.isNot(tok::eof)) {
@@ -473,6 +474,13 @@ Parser::ParseUsingDirectiveOrDeclaration(DeclaratorContext Context,
return nullptr;
}
+ // Consume unexpected 'template' keywords.
+ while (Tok.is(tok::kw_template)) {
+ SourceLocation TemplateLoc = ConsumeToken();
+ Diag(TemplateLoc, diag::err_unexpected_template_after_using)
+ << FixItHint::CreateRemoval(TemplateLoc);
+ }
+
// 'using namespace' means this is a using-directive.
if (Tok.is(tok::kw_namespace)) {
// Template parameters are always an error here.
@@ -1248,9 +1256,11 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
case tok::ampamp: // struct foo {...} && R = ...
case tok::identifier: // struct foo {...} V ;
case tok::r_paren: //(struct foo {...} ) {4}
+ case tok::coloncolon: // struct foo {...} :: a::b;
case tok::annot_cxxscope: // struct foo {...} a:: b;
case tok::annot_typename: // struct foo {...} a ::b;
case tok::annot_template_id: // struct foo {...} a<int> ::b;
+ case tok::kw_decltype: // struct foo {...} decltype (a)::b;
case tok::l_paren: // struct foo {...} ( x);
case tok::comma: // __builtin_offsetof(struct foo{...} ,
case tok::kw_operator: // struct foo operator ++() {...}
@@ -2539,6 +2549,13 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// Eat 'using'.
SourceLocation UsingLoc = ConsumeToken();
+ // Consume unexpected 'template' keywords.
+ while (Tok.is(tok::kw_template)) {
+ SourceLocation TemplateLoc = ConsumeToken();
+ Diag(TemplateLoc, diag::err_unexpected_template_after_using)
+ << FixItHint::CreateRemoval(TemplateLoc);
+ }
+
if (Tok.is(tok::kw_namespace)) {
Diag(UsingLoc, diag::err_using_namespace_in_class);
SkipUntil(tok::semi, StopBeforeMatch);
@@ -3048,9 +3065,14 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));
return nullptr;
+ case tok::kw_private:
+ // FIXME: We don't accept GNU attributes on access specifiers in OpenCL mode
+ // yet.
+ if (getLangOpts().OpenCL && !NextToken().is(tok::colon))
+ return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
+ LLVM_FALLTHROUGH;
case tok::kw_public:
- case tok::kw_protected:
- case tok::kw_private: {
+ case tok::kw_protected: {
AccessSpecifier NewAS = getAccessSpecifierIfPresent();
assert(NewAS != AS_none);
// Current token is a C++ access specifier.
@@ -3110,6 +3132,12 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
TagType == DeclSpec::TST_union ||
TagType == DeclSpec::TST_class) && "Invalid TagType!");
+ llvm::TimeTraceScope TimeScope("ParseClass", [&]() {
+ if (auto *TD = dyn_cast_or_null<NamedDecl>(TagDecl))
+ return TD->getQualifiedNameAsString();
+ return std::string("<anonymous>");
+ });
+
PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,
"parsing struct/union/class body");
@@ -3482,20 +3510,20 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
// Parse the optional expression-list.
ExprVector ArgExprs;
CommaLocsTy CommaLocs;
+ auto RunSignatureHelp = [&] {
+ QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp(
+ getCurScope(), ConstructorDecl, SS, TemplateTypeTy, ArgExprs, II,
+ T.getOpenLocation());
+ CalledSignatureHelp = true;
+ return PreferredType;
+ };
if (Tok.isNot(tok::r_paren) &&
ParseExpressionList(ArgExprs, CommaLocs, [&] {
- QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp(
- getCurScope(), ConstructorDecl, SS, TemplateTypeTy, ArgExprs, II,
- T.getOpenLocation());
- CalledSignatureHelp = true;
- Actions.CodeCompleteExpression(getCurScope(), PreferredType);
+ PreferredType.enterFunctionArgument(Tok.getLocation(),
+ RunSignatureHelp);
})) {
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
- Actions.ProduceCtorInitMemberSignatureHelp(
- getCurScope(), ConstructorDecl, SS, TemplateTypeTy, ArgExprs, II,
- T.getOpenLocation());
- CalledSignatureHelp = true;
- }
+ if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ RunSignatureHelp();
SkipUntil(tok::r_paren, StopAtSemi);
return true;
}