20#include "llvm/ADT/ScopeExit.h"
25 if (!Tok.
is(tok::l_paren))
31 if (isTokenStringLiteral()) {
36 ? diag::warn_cxx23_delete_with_message
37 : diag::ext_delete_with_message)
38 << Message->getSourceRange();
50void Parser::SkipDeletedFunctionBody() {
51 if (!Tok.
is(tok::l_paren))
59 if (Tok.
is(tok::r_paren))
63NamedDecl *Parser::ParseCXXInlineMethodDef(
67 assert(
D.isFunctionDeclarator() &&
"This isn't a function declarator!");
68 assert(Tok.
isOneOf(tok::l_brace, tok::colon, tok::kw_try, tok::equal) &&
69 "Current token not a '{', ':', '=', or 'try'!");
72 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()
74 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
77 if (
D.getDeclSpec().isFriendSpecified())
82 TemplateParams,
nullptr,
92 HandleMemberFunctionDeclDelays(
D, FnD);
107 ? diag::warn_cxx98_compat_defaulted_deleted_function
108 : diag::ext_defaulted_deleted_function)
113 if (
auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) {
114 DeclAsFunction->setRangeEnd(KWEndLoc);
118 ? diag::warn_cxx98_compat_defaulted_deleted_function
119 : diag::ext_defaulted_deleted_function)
122 if (
auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) {
123 DeclAsFunction->setRangeEnd(KWEndLoc);
126 llvm_unreachable(
"function definition after = not 'delete' or 'default'");
129 if (Tok.
is(tok::comma)) {
130 Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
133 }
else if (ExpectAndConsume(tok::semi, diag::err_expected_after,
134 Delete ?
"delete" :
"default")) {
142 trySkippingFunctionBody()) {
152 !
D.getDeclSpec().hasConstexprSpecifier() &&
161 LexTemplateFunctionForLateParsing(Toks);
174 LexedMethod* LM =
new LexedMethod(
this, FnD);
175 getCurrentClass().LateParsedDeclarations.push_back(LM);
181 if (ConsumeAndStoreFunctionPrologue(Toks)) {
188 llvm::any_of(Toks, [](
const Token &Tok) {
189 return Tok.is(tok::code_completion);
202 delete getCurrentClass().LateParsedDeclarations.back();
203 getCurrentClass().LateParsedDeclarations.pop_back();
207 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
211 if (kind == tok::kw_try) {
212 while (Tok.
is(tok::kw_catch)) {
213 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
214 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
227 delete getCurrentClass().LateParsedDeclarations.back();
228 getCurrentClass().LateParsedDeclarations.pop_back();
234void Parser::ParseCXXNonStaticMemberInitializer(
Decl *VarD) {
235 assert(Tok.
isOneOf(tok::l_brace, tok::equal) &&
236 "Current token not a '{' or '='!");
238 LateParsedMemberInitializer *MI =
239 new LateParsedMemberInitializer(
this, VarD);
240 getCurrentClass().LateParsedDeclarations.push_back(MI);
244 if (kind == tok::equal) {
249 if (kind == tok::l_brace) {
255 ConsumeAndStoreUntil(tok::r_brace, Toks,
true);
271Parser::LateParsedDeclaration::~LateParsedDeclaration() {}
272void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {}
273void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {}
274void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {}
275void Parser::LateParsedDeclaration::ParseLexedAttributes() {}
276void Parser::LateParsedDeclaration::ParseLexedPragmas() {}
278Parser::LateParsedClass::LateParsedClass(
Parser *
P, ParsingClass *
C)
281Parser::LateParsedClass::~LateParsedClass() {
282 Self->DeallocateParsedClasses(Class);
285void Parser::LateParsedClass::ParseLexedMethodDeclarations() {
286 Self->ParseLexedMethodDeclarations(*Class);
289void Parser::LateParsedClass::ParseLexedMemberInitializers() {
290 Self->ParseLexedMemberInitializers(*Class);
293void Parser::LateParsedClass::ParseLexedMethodDefs() {
294 Self->ParseLexedMethodDefs(*Class);
297void Parser::LateParsedClass::ParseLexedAttributes() {
298 Self->ParseLexedAttributes(*Class);
301void Parser::LateParsedClass::ParseLexedPragmas() {
302 Self->ParseLexedPragmas(*Class);
305void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() {
306 Self->ParseLexedMethodDeclaration(*
this);
309void Parser::LexedMethod::ParseLexedMethodDefs() {
310 Self->ParseLexedMethodDef(*
this);
313void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() {
314 Self->ParseLexedMemberInitializer(*
this);
317void Parser::LateParsedAttribute::ParseLexedAttributes() {
318 Self->ParseLexedAttribute(*
this,
true,
false);
321void Parser::LateParsedPragma::ParseLexedPragmas() {
322 Self->ParseLexedPragma(*
this);
344 !
Class.TopLevelClass),
347 if (
Class.TopLevelClass)
353 Class.TagOrTemplate);
356 if (
Class.TopLevelClass)
360 Class.TagOrTemplate);
364void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
365 ReenterClassScopeRAII InClassScope(*
this,
Class);
367 for (LateParsedDeclaration *LateD :
Class.LateParsedDeclarations)
368 LateD->ParseLexedMethodDeclarations();
371void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
373 ReenterTemplateScopeRAII InFunctionTemplateScope(*
this, LM.Method);
383 for (
unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
384 auto Param = cast<ParmVarDecl>(LM.DefaultArgs[I].Param);
386 bool HasUnparsed = Param->hasUnparsedDefaultArg();
388 std::unique_ptr<CachedTokens> Toks = std::move(LM.DefaultArgs[I].Toks);
394 Token LastDefaultArgToken = Toks->back();
400 Toks->push_back(DefArgEnd);
403 Toks->push_back(Tok);
404 PP.EnterTokenStream(*Toks,
true,
true);
410 assert(Tok.
is(tok::equal) &&
"Default argument not starting with '='");
421 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
422 DefArgResult = ParseBraceInitializer();
433 assert(Toks->size() >= 3 &&
"expected a token in default arg");
436 (*Toks)[Toks->size() - 3].getLocation());
444 while (Tok.
isNot(tok::eof))
449 }
else if (HasUnparsed) {
450 assert(Param->hasInheritedDefaultArg());
452 if (
const auto *FunTmpl = dyn_cast<FunctionTemplateDecl>(LM.Method))
461 Param->setUninstantiatedDefaultArg(
464 Param->setDefaultArg(OldParam->
getInit());
474 Token LastExceptionSpecToken = Toks->back();
475 Token ExceptionSpecEnd;
477 ExceptionSpecEnd.
setKind(tok::eof);
480 Toks->push_back(ExceptionSpecEnd);
483 Toks->push_back(Tok);
484 PP.EnterTokenStream(*Toks,
true,
true);
498 = dyn_cast<FunctionTemplateDecl>(LM.Method))
499 FunctionToPush = FunTmpl->getTemplatedDecl();
501 FunctionToPush = cast<FunctionDecl>(LM.Method);
502 Method = dyn_cast<CXXMethodDecl>(FunctionToPush);
532 = tryParseExceptionSpecification(
false, SpecificationRange,
534 DynamicExceptionRanges, NoexceptExpr,
535 ExceptionSpecTokens);
544 DynamicExceptionRanges,
546 NoexceptExpr.
get() :
nullptr);
550 while (Tok.
isNot(tok::eof))
558 LM.ExceptionSpecTokens =
nullptr;
561 InFunctionTemplateScope.Scopes.Exit();
567void Parser::ParseLexedMethodDefs(ParsingClass &
Class) {
568 ReenterClassScopeRAII InClassScope(*
this,
Class);
570 for (LateParsedDeclaration *
D :
Class.LateParsedDeclarations)
571 D->ParseLexedMethodDefs();
574void Parser::ParseLexedMethodDef(LexedMethod &LM) {
576 ReenterTemplateScopeRAII InFunctionTemplateScope(*
this, LM.D);
580 assert(!LM.Toks.empty() &&
"Empty body!");
581 Token LastBodyToken = LM.Toks.back();
587 LM.Toks.push_back(BodyEnd);
590 LM.Toks.push_back(Tok);
591 PP.EnterTokenStream(LM.Toks,
true,
true);
595 assert(Tok.
isOneOf(tok::l_brace, tok::colon, tok::kw_try)
596 &&
"Inline method not starting with '{', ':' or 'try'");
606 auto _ = llvm::make_scope_exit([&]() {
607 while (Tok.
isNot(tok::eof))
613 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))
614 if (isa<CXXMethodDecl>(FD) ||
619 if (Tok.
is(tok::kw_try)) {
620 ParseFunctionTryBlock(LM.D, FnScope);
623 if (Tok.
is(tok::colon)) {
624 ParseConstructorInitializer(LM.D);
627 if (!Tok.
is(tok::l_brace)) {
636 !isa<FunctionTemplateDecl>(LM.D) ||
637 cast<FunctionTemplateDecl>(LM.D)->getTemplateParameters()->getDepth()
638 < TemplateParameterDepth) &&
639 "TemplateParameterDepth should be greater than the depth of "
640 "current template being instantiated!");
642 ParseFunctionStatementBody(LM.D, FnScope);
645void Parser::ParseLexedMemberInitializers(ParsingClass &
Class) {
646 ReenterClassScopeRAII InClassScope(*
this,
Class);
648 if (!
Class.LateParsedDeclarations.empty()) {
658 for (LateParsedDeclaration *
D :
Class.LateParsedDeclarations)
659 D->ParseLexedMemberInitializers();
665void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
666 if (!MI.Field || MI.Field->isInvalidDecl())
673 MI.Toks.push_back(Tok);
674 PP.EnterTokenStream(MI.Toks,
true,
true);
694 if (Tok.
isNot(tok::eof)) {
695 if (!
Init.isInvalid()) {
700 Diag(EndLoc, diag::err_expected_semi_decl_list);
704 while (Tok.
isNot(tok::eof))
712void Parser::ParseLexedAttributes(ParsingClass &
Class) {
713 ReenterClassScopeRAII InClassScope(*
this,
Class);
715 for (LateParsedDeclaration *LateD :
Class.LateParsedDeclarations)
716 LateD->ParseLexedAttributes();
719void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs,
Decl *
D,
720 bool EnterScope,
bool OnDefinition) {
721 assert(LAs.parseSoon() &&
722 "Attribute list should be marked for immediate parsing.");
723 for (
unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
726 ParseLexedAttribute(*LAs[i],
EnterScope, OnDefinition);
732void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
733 bool EnterScope,
bool OnDefinition) {
741 LA.Toks.push_back(AttrEnd);
745 LA.Toks.push_back(Tok);
746 PP.EnterTokenStream(LA.Toks,
true,
true);
752 if (LA.Decls.size() > 0) {
753 Decl *
D = LA.Decls[0];
761 if (LA.Decls.size() == 1) {
763 ReenterTemplateScopeRAII InDeclScope(*
this,
D,
EnterScope);
773 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
782 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
787 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
790 if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&
791 Attrs.begin()->isKnownToGCC())
792 Diag(Tok, diag::warn_attribute_on_function_definition)
795 for (
unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i)
800 while (Tok.
isNot(tok::eof))
807void Parser::ParseLexedPragmas(ParsingClass &
Class) {
808 ReenterClassScopeRAII InClassScope(*
this,
Class);
810 for (LateParsedDeclaration *
D :
Class.LateParsedDeclarations)
811 D->ParseLexedPragmas();
814void Parser::ParseLexedPragma(LateParsedPragma &LP) {
816 PP.EnterTokenStream(LP.toks(),
true,
821 assert(Tok.
isAnnotation() &&
"Expected annotation token.");
823 case tok::annot_attr_openmp:
824 case tok::annot_pragma_openmp: {
827 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
831 llvm_unreachable(
"Unexpected token.");
837 bool StopAtSemi,
bool ConsumeFinalToken) {
840 bool isFirstTokenConsumed =
true;
843 if (Tok.
is(T1) || Tok.
is(T2)) {
844 if (ConsumeFinalToken) {
853 case tok::annot_module_begin:
854 case tok::annot_module_end:
855 case tok::annot_module_include:
856 case tok::annot_repl_input_end:
864 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
870 ConsumeAndStoreUntil(tok::r_square, Toks,
false);
876 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
885 if (ParenCount && !isFirstTokenConsumed)
891 if (BracketCount && !isFirstTokenConsumed)
897 if (BraceCount && !isFirstTokenConsumed)
913 isFirstTokenConsumed =
false;
917bool Parser::ConsumeAndStoreFunctionPrologue(
CachedTokens &Toks) {
918 if (Tok.
is(tok::kw_try)) {
923 if (Tok.
isNot(tok::colon)) {
929 ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks,
932 if (Tok.
isNot(tok::l_brace))
953 bool MightBeTemplateArgument =
false;
957 if (Tok.
is(tok::kw_decltype)) {
960 if (Tok.
isNot(tok::l_paren))
965 if (!ConsumeAndStoreUntil(tok::r_paren, Toks,
true)) {
967 Diag(OpenLoc, diag::note_matching) << tok::l_paren;
973 if (Tok.
is(tok::coloncolon)) {
977 if (Tok.
is(tok::kw_template)) {
983 if (Tok.
is(tok::identifier)) {
990 if (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::l_square)) {
995 if (!ConsumeAndStoreUntil(tok::r_square, Toks,
true)) {
997 Diag(OpenLoc, diag::note_matching) << tok::l_square;
1002 }
while (Tok.
is(tok::coloncolon));
1004 if (Tok.
is(tok::code_completion)) {
1005 Toks.push_back(Tok);
1006 ConsumeCodeCompletionToken();
1007 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype)) {
1014 if (Tok.
is(tok::comma)) {
1016 Toks.push_back(Tok);
1020 if (Tok.
is(tok::less))
1021 MightBeTemplateArgument =
true;
1023 if (MightBeTemplateArgument) {
1030 if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks,
1037 }
else if (Tok.
isNot(tok::l_paren) && Tok.
isNot(tok::l_brace)) {
1041 << tok::l_paren << tok::l_brace;
1047 Toks.push_back(Tok);
1048 bool IsLParen = (
kind == tok::l_paren);
1054 assert(kind == tok::l_brace &&
"Must be left paren or brace here.");
1061 const Token &PreviousToken = Toks[Toks.size() - 2];
1062 if (!MightBeTemplateArgument &&
1063 !PreviousToken.
isOneOf(tok::identifier, tok::greater,
1064 tok::greatergreater)) {
1070 TentativeParsingAction PA(*
this);
1072 !Tok.
isOneOf(tok::comma, tok::ellipsis, tok::l_brace)) {
1085 tok::TokenKind CloseKind = IsLParen ? tok::r_paren : tok::r_brace;
1086 if (!ConsumeAndStoreUntil(CloseKind, Toks,
true)) {
1087 Diag(Tok, diag::err_expected) << CloseKind;
1088 Diag(OpenLoc, diag::note_matching) <<
kind;
1093 if (Tok.
is(tok::ellipsis)) {
1094 Toks.push_back(Tok);
1100 if (Tok.
is(tok::comma)) {
1101 Toks.push_back(Tok);
1103 }
else if (Tok.
is(tok::l_brace)) {
1118 Toks.push_back(Tok);
1121 }
else if (!MightBeTemplateArgument) {
1122 return Diag(Tok.
getLocation(), diag::err_expected_either) << tok::l_brace
1128bool Parser::ConsumeAndStoreConditional(
CachedTokens &Toks) {
1130 assert(Tok.
is(tok::question));
1131 Toks.push_back(Tok);
1134 while (Tok.
isNot(tok::colon)) {
1135 if (!ConsumeAndStoreUntil(tok::question, tok::colon, Toks,
1141 if (Tok.
is(tok::question) && !ConsumeAndStoreConditional(Toks))
1146 Toks.push_back(Tok);
1151bool Parser::ConsumeAndStoreInitializer(
CachedTokens &Toks,
1154 bool IsFirstToken =
true;
1159 unsigned AngleCount = 0;
1160 unsigned KnownTemplateCount = 0;
1167 if (ParenCount == 1 &&
NextToken().is(tok::r_paren))
1175 if (KnownTemplateCount)
1188 TentativeParsingAction TPA(*
this,
true);
1191 TPResult
Result = TPResult::Error;
1195 Result = TryParseInitDeclaratorList();
1198 if (
Result == TPResult::Ambiguous && Tok.
isNot(tok::semi))
1199 Result = TPResult::False;
1203 bool InvalidAsDeclaration =
false;
1204 Result = TryParseParameterDeclarationClause(
1205 &InvalidAsDeclaration,
true);
1208 if (
Result == TPResult::Ambiguous && InvalidAsDeclaration)
1209 Result = TPResult::False;
1219 if (
Result != TPResult::False &&
Result != TPResult::Error)
1224 ++KnownTemplateCount;
1240 if (!ConsumeAndStoreConditional(Toks))
1244 case tok::greatergreatergreater:
1247 if (AngleCount) --AngleCount;
1248 if (KnownTemplateCount) --KnownTemplateCount;
1250 case tok::greatergreater:
1253 if (AngleCount) --AngleCount;
1254 if (KnownTemplateCount) --KnownTemplateCount;
1257 if (AngleCount) --AngleCount;
1258 if (KnownTemplateCount) --KnownTemplateCount;
1261 case tok::kw_template:
1265 Toks.push_back(Tok);
1267 if (Tok.
is(tok::identifier)) {
1268 Toks.push_back(Tok);
1270 if (Tok.
is(tok::less)) {
1272 ++KnownTemplateCount;
1273 Toks.push_back(Tok);
1279 case tok::kw_operator:
1282 Toks.push_back(Tok);
1286 case tok::greatergreatergreater:
1287 case tok::greatergreater:
1290 Toks.push_back(Tok);
1300 Toks.push_back(Tok);
1302 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
1306 Toks.push_back(Tok);
1308 ConsumeAndStoreUntil(tok::r_square, Toks,
false);
1312 Toks.push_back(Tok);
1314 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
1326 if (ParenCount && !IsFirstToken)
1328 Toks.push_back(Tok);
1332 if (BracketCount && !IsFirstToken)
1334 Toks.push_back(Tok);
1338 if (BraceCount && !IsFirstToken)
1340 Toks.push_back(Tok);
1344 case tok::code_completion:
1345 Toks.push_back(Tok);
1346 ConsumeCodeCompletionToken();
1349 case tok::string_literal:
1350 case tok::wide_string_literal:
1351 case tok::utf8_string_literal:
1352 case tok::utf16_string_literal:
1353 case tok::utf32_string_literal:
1354 Toks.push_back(Tok);
1355 ConsumeStringToken();
1368 Toks.push_back(Tok);
1372 IsFirstToken =
false;
Defines the C++ template declaration subclasses.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
Represents a static or instance method of a struct/union/class.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Decl - This represents one declaration (or definition), e.g.
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
bool isInIdentifierNamespace(unsigned NS) const
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
@ IDNS_OrdinaryFriend
This declaration is a friend function.
DeclContext * getDeclContext()
bool hasErrorOccurred() const
RAII object that enters a new expression evaluation context.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
QualType getReturnType() const
void setWillHaveBody(bool V=true)
Declaration of a template function.
This represents a decl that may have a name.
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
Represents a parameter to a function.
bool hasUnparsedDefaultArg() const
Determines whether this parameter has a default argument that has not yet been parsed.
bool hasUninstantiatedDefaultArg() const
Expr * getUninstantiatedDefaultArg()
ParsedAttributes - A collection of parsed attributes.
Introduces zero or more scopes for parsing.
void Enter(unsigned ScopeFlags)
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
const LangOptions & getLangOpts() const
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtSemi
Stop skipping at semicolon.
ExprResult ParseUnevaluatedStringLiteralExpression()
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D)
Re-enter a possible template scope, creating as many template parameter scopes as necessary.
A class for parsing a declarator.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
bool isCodeCompletionEnabled() const
Determine if we are performing code completion.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
The collection of all-type qualifiers we support.
Represents a struct/union/class.
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Scope - A scope is a transient data structure that is used while parsing the program.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ DeclScope
This is a scope that can contain a declaration.
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Records and restores the CurFPFeatures state on entry/exit of compound statements.
RAII class used to indicate that we are performing provisional semantic analysis to determine the val...
Decl * ActOnSkippedFunctionBody(Decl *Decl)
void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc, Expr *DefaultArg)
ActOnParamDefaultArgumentError - Parsing or semantic analysis of the default argument for the paramet...
void ActOnFinishDelayedMemberInitializers(Decl *Record)
void ActOnExitFunctionContext()
NamedDecl * ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, Expr *BitfieldWidth, const VirtSpecifiers &VS, InClassInitStyle InitStyle)
ActOnCXXMemberDeclarator - This is invoked when a C++ class member declarator is parsed.
Decl * ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation=false, bool RetainFunctionScopeInfo=false)
Performs semantic analysis at the end of a function body.
bool IsInsideALocalClassWithinATemplateFunction()
void ActOnReenterFunctionContext(Scope *S, Decl *D)
Push the parameters of D, which must be a function, into scope.
void ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, Expr *defarg)
ActOnParamDefaultArgument - Check whether the default argument provided for a function parameter is w...
void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method)
ActOnFinishDelayedCXXMethodDeclaration - We have finished processing the delayed method declaration f...
DiagnosticsEngine & getDiagnostics() const
NamedDecl * ActOnFriendFunctionDecl(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParams)
void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD, CachedTokens &Toks)
void ActOnStartCXXInClassMemberInitializer()
Enter a new C++ default initializer scope.
void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record)
void PushFunctionScope()
Enter a new function scope.
void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc)
Decl * ActOnStartOfFunctionDef(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, SkipBodyInfo *SkipBody=nullptr, FnBodyKind BodyKind=FnBodyKind::Other)
void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())
ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...
void CheckForFunctionRedefinition(FunctionDecl *FD, const FunctionDecl *EffectiveDefinition=nullptr, SkipBodyInfo *SkipBody=nullptr)
void ActOnFinishInlineFunctionDef(FunctionDecl *D)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool canSkipFunctionBody(Decl *D)
Determine whether we can skip parsing the body of a function definition, assuming we don't care about...
void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc, ExprResult Init)
This is invoked after parsing an in-class initializer for a non-static C++ class member,...
void ActOnDefaultCtorInitializers(Decl *CDtorDecl)
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
void actOnDelayedExceptionSpecification(Decl *D, ExceptionSpecificationType EST, SourceRange SpecificationRange, ArrayRef< ParsedType > DynamicExceptions, ArrayRef< SourceRange > DynamicExceptionRanges, Expr *NoexceptExpr)
Add an exception-specification to the given member or friend function (or function template).
void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc, StringLiteral *Message=nullptr)
void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method)
ActOnStartDelayedCXXMethodDeclaration - We have completed parsing a top-level (non-nested) C++ class,...
void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs)
ActOnFinishDelayedAttribute - Invoked when we have finished parsing an attribute for which parsing is...
void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc)
void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record)
void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param)
ActOnDelayedCXXMethodParameter - We've already started a delayed C++ method declaration.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
Token - This structure provides full information about a lexed token.
SourceLocation getEndLoc() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isOneOf(Ts... Ks) const
void setEofData(const void *D)
void setLocation(SourceLocation L)
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
const void * getEofData() const
void startToken()
Reset all flags to cleared.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
const Expr * getInit() const
Represents a C++11 virt-specifier-seq.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ ICIS_NoInit
No in-class initializer.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Delete
'delete' clause, allowed on the 'exit data' construct.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
@ Result
The result type of a method or function.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ NonTemplate
We are not parsing a template at all.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
ReenterClassScopeRAII(Parser &P, ParsingClass &Class)
ReenterTemplateScopeRAII(Parser &P, Decl *MaybeTemplated, bool Enter=true)
TemplateParameterDepthRAII CurTemplateDepthTracker
An RAII helper that pops function a function scope on exit.