ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, Scope *CurScope, bool IsInstantiation) { // Collect information from the lambda scope. SmallVector<LambdaExpr::Capture, 4> Captures; SmallVector<Expr *, 4> CaptureInits; LambdaCaptureDefault CaptureDefault; CXXRecordDecl *Class; CXXMethodDecl *CallOperator; SourceRange IntroducerRange; bool ExplicitParams; bool ExplicitResultType; bool LambdaExprNeedsCleanups; bool ContainsUnexpandedParameterPack; SmallVector<VarDecl *, 4> ArrayIndexVars; SmallVector<unsigned, 4> ArrayIndexStarts; { LambdaScopeInfo *LSI = getCurLambda(); CallOperator = LSI->CallOperator; Class = LSI->Lambda; IntroducerRange = LSI->IntroducerRange; ExplicitParams = LSI->ExplicitParams; ExplicitResultType = !LSI->HasImplicitReturnType; LambdaExprNeedsCleanups = LSI->ExprNeedsCleanups; ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack; ArrayIndexVars.swap(LSI->ArrayIndexVars); ArrayIndexStarts.swap(LSI->ArrayIndexStarts); // Translate captures. for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) { LambdaScopeInfo::Capture From = LSI->Captures[I]; assert(!From.isBlockCapture() && "Cannot capture __block variables"); bool IsImplicit = I >= LSI->NumExplicitCaptures; // Handle 'this' capture. if (From.isThisCapture()) { Captures.push_back(LambdaExpr::Capture(From.getLocation(), IsImplicit, LCK_This)); CaptureInits.push_back(new (Context) CXXThisExpr(From.getLocation(), getCurrentThisType(), /*isImplicit=*/true)); continue; } VarDecl *Var = From.getVariable(); LambdaCaptureKind Kind = From.isCopyCapture()? LCK_ByCopy : LCK_ByRef; Captures.push_back(LambdaExpr::Capture(From.getLocation(), IsImplicit, Kind, Var, From.getEllipsisLoc())); CaptureInits.push_back(From.getCopyExpr()); } switch (LSI->ImpCaptureStyle) { case CapturingScopeInfo::ImpCap_None: CaptureDefault = LCD_None; break; case CapturingScopeInfo::ImpCap_LambdaByval: CaptureDefault = LCD_ByCopy; break; case CapturingScopeInfo::ImpCap_CapturedRegion: case CapturingScopeInfo::ImpCap_LambdaByref: CaptureDefault = LCD_ByRef; break; case CapturingScopeInfo::ImpCap_Block: llvm_unreachable("block capture in lambda"); break; } // C++11 [expr.prim.lambda]p4: // If a lambda-expression does not include a // trailing-return-type, it is as if the trailing-return-type // denotes the following type: // FIXME: Assumes current resolution to core issue 975. if (LSI->HasImplicitReturnType) { deduceClosureReturnType(*LSI); // - if there are no return statements in the // compound-statement, or all return statements return // either an expression of type void or no expression or // braced-init-list, the type void; if (LSI->ReturnType.isNull()) { LSI->ReturnType = Context.VoidTy; } // Create a function type with the inferred return type. const FunctionProtoType *Proto = CallOperator->getType()->getAs<FunctionProtoType>(); QualType FunctionTy = Context.getFunctionType(LSI->ReturnType, ArrayRef<QualType>(Proto->arg_type_begin(), Proto->getNumArgs()), Proto->getExtProtoInfo()); CallOperator->setType(FunctionTy); } // C++ [expr.prim.lambda]p7: // The lambda-expression's compound-statement yields the // function-body (8.4) of the function call operator [...]. ActOnFinishFunctionBody(CallOperator, Body, IsInstantiation); CallOperator->setLexicalDeclContext(Class); Class->addDecl(CallOperator); PopExpressionEvaluationContext(); // C++11 [expr.prim.lambda]p6: // The closure type for a lambda-expression with no lambda-capture // has a public non-virtual non-explicit const conversion function // to pointer to function having the same parameter and return // types as the closure type's function call operator. if (Captures.empty() && CaptureDefault == LCD_None) addFunctionPointerConversion(*this, IntroducerRange, Class, CallOperator); // Objective-C++: // The closure type for a lambda-expression has a public non-virtual // non-explicit const conversion function to a block pointer having the // same parameter and return types as the closure type's function call // operator. if (getLangOpts().Blocks && getLangOpts().ObjC1) addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator); // Finalize the lambda class. SmallVector<Decl*, 4> Fields; for (RecordDecl::field_iterator i = Class->field_begin(), e = Class->field_end(); i != e; ++i) Fields.push_back(*i); ActOnFields(0, Class->getLocation(), Class, Fields, SourceLocation(), SourceLocation(), 0); CheckCompletedCXXClass(Class); } if (LambdaExprNeedsCleanups) ExprNeedsCleanups = true; LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange, CaptureDefault, Captures, ExplicitParams, ExplicitResultType, CaptureInits, ArrayIndexVars, ArrayIndexStarts, Body->getLocEnd(), ContainsUnexpandedParameterPack); // C++11 [expr.prim.lambda]p2: // A lambda-expression shall not appear in an unevaluated operand // (Clause 5). if (!CurContext->isDependentContext()) { switch (ExprEvalContexts.back().Context) { case Unevaluated: case UnevaluatedAbstract: // We don't actually diagnose this case immediately, because we // could be within a context where we might find out later that // the expression is potentially evaluated (e.g., for typeid). ExprEvalContexts.back().Lambdas.push_back(Lambda); break; case ConstantEvaluated: case PotentiallyEvaluated: case PotentiallyEvaluatedIfUsed: break; } } return MaybeBindToTemporary(Lambda); }
/// ReadFunctionLikeMacroArgs - After reading "MACRO" and knowing that the next /// token is the '(' of the macro, this method is invoked to read all of the /// actual arguments specified for the macro invocation. This returns null on /// error. MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI, SourceLocation &MacroEnd) { // The number of fixed arguments to parse. unsigned NumFixedArgsLeft = MI->getNumParams(); bool isVariadic = MI->isVariadic(); // Outer loop, while there are more arguments, keep reading them. Token Tok; // Read arguments as unexpanded tokens. This avoids issues, e.g., where // an argument value in a macro could expand to ',' or '(' or ')'. LexUnexpandedToken(Tok); assert(Tok.is(tok::l_paren) && "Error computing l-paren-ness?"); // ArgTokens - Build up a list of tokens that make up each argument. Each // argument is separated by an EOF token. Use a SmallVector so we can avoid // heap allocations in the common case. SmallVector<Token, 64> ArgTokens; bool FoundElidedComma = false; SourceLocation TooManyArgsLoc; unsigned NumActuals = 0; while (Tok.isNot(tok::r_paren)) { assert(Tok.isOneOf(tok::l_paren, tok::comma) && "only expect argument separators here"); size_t ArgTokenStart = ArgTokens.size(); SourceLocation ArgStartLoc = Tok.getLocation(); // C99 6.10.3p11: Keep track of the number of l_parens we have seen. Note // that we already consumed the first one. unsigned NumParens = 0; while (true) { // Read arguments as unexpanded tokens. This avoids issues, e.g., where // an argument value in a macro could expand to ',' or '(' or ')'. LexUnexpandedToken(Tok); if (Tok.isOneOf(tok::eof, tok::eod)) { // "#if f(<eof>" & "#if f(\n" Diag(MacroName, diag::err_unterm_macro_invoc); Diag(MI->getDefinitionLoc(), diag::note_macro_here) << MacroName.getIdentifierInfo(); // Do not lose the EOF/EOD. Return it to the client. MacroName = Tok; return nullptr; } else if (Tok.is(tok::r_paren)) { // If we found the ) token, the macro arg list is done. if (NumParens-- == 0) { MacroEnd = Tok.getLocation(); if (!ArgTokens.empty() && ArgTokens.back().commaAfterElided()) { FoundElidedComma = true; } break; } } else if (Tok.is(tok::l_paren)) { ++NumParens; } else if (Tok.is(tok::comma) && NumParens == 0 && !(Tok.getFlags() & Token::IgnoredComma)) { // In Microsoft-compatibility mode, single commas from nested macro // expansions should not be considered as argument separators. We test // for this with the IgnoredComma token flag above. // Comma ends this argument if there are more fixed arguments expected. // However, if this is a variadic macro, and this is part of the // variadic part, then the comma is just an argument token. if (!isVariadic) break; if (NumFixedArgsLeft > 1) break; } else if (Tok.is(tok::comment)) { // If this is a comment token in the argument list and we're just in // -C mode (not -CC mode), discard the comment. continue; } else if (Tok.getIdentifierInfo() != nullptr) { // Reading macro arguments can cause macros that we are currently // expanding from to be popped off the expansion stack. Doing so causes // them to be reenabled for expansion. Here we record whether any // identifiers we lex as macro arguments correspond to disabled macros. // If so, we mark the token as noexpand. This is a subtle aspect of // C99 6.10.3.4p2. if (MacroInfo *MI = getMacroInfo(Tok.getIdentifierInfo())) if (!MI->isEnabled()) Tok.setFlag(Token::DisableExpand); } ArgTokens.push_back(Tok); } // If this was an empty argument list foo(), don't add this as an empty // argument. if (ArgTokens.empty() && Tok.getKind() == tok::r_paren) break; // If this is not a variadic macro, and too many args were specified, emit // an error. if (!isVariadic && NumFixedArgsLeft == 0 && TooManyArgsLoc.isInvalid()) { if (ArgTokens.size() != ArgTokenStart) TooManyArgsLoc = ArgTokens[ArgTokenStart].getLocation(); else TooManyArgsLoc = ArgStartLoc; } // Add a marker EOF token to the end of the token list for this argument. Token EOFTok; EOFTok.startToken(); EOFTok.setKind(tok::eof); EOFTok.setLocation(Tok.getLocation()); EOFTok.setLength(0); ArgTokens.push_back(EOFTok); ++NumActuals; if (NumFixedArgsLeft != 0) --NumFixedArgsLeft; } // Okay, we either found the r_paren. Check to see if we parsed too few // arguments. unsigned MinArgsExpected = MI->getNumParams(); // If this is not a variadic macro, and too many args were specified, emit // an error. if (!isVariadic && NumActuals > MinArgsExpected) { // Emit the diagnostic at the macro name in case there is a missing ). // Emitting it at the , could be far away from the macro name. Diag(TooManyArgsLoc, diag::err_too_many_args_in_macro_invoc); Diag(MI->getDefinitionLoc(), diag::note_macro_here) << MacroName.getIdentifierInfo(); // Commas from braced initializer lists will be treated as argument // separators inside macros. Attempt to correct for this with parentheses. // TODO: See if this can be generalized to angle brackets for templates // inside macro arguments. SmallVector<Token, 4> FixedArgTokens; unsigned FixedNumArgs = 0; SmallVector<SourceRange, 4> ParenHints, InitLists; if (!GenerateNewArgTokens(*this, ArgTokens, FixedArgTokens, FixedNumArgs, ParenHints, InitLists)) { if (!InitLists.empty()) { DiagnosticBuilder DB = Diag(MacroName, diag::note_init_list_at_beginning_of_macro_argument); for (SourceRange Range : InitLists) DB << Range; } return nullptr; } if (FixedNumArgs != MinArgsExpected) return nullptr; DiagnosticBuilder DB = Diag(MacroName, diag::note_suggest_parens_for_macro); for (SourceRange ParenLocation : ParenHints) { DB << FixItHint::CreateInsertion(ParenLocation.getBegin(), "("); DB << FixItHint::CreateInsertion(ParenLocation.getEnd(), ")"); } ArgTokens.swap(FixedArgTokens); NumActuals = FixedNumArgs; } // See MacroArgs instance var for description of this. bool isVarargsElided = false; if (NumActuals < MinArgsExpected) { // There are several cases where too few arguments is ok, handle them now. if (NumActuals == 0 && MinArgsExpected == 1) { // #define A(X) or #define A(...) ---> A() // If there is exactly one argument, and that argument is missing, // then we have an empty "()" argument empty list. This is fine, even if // the macro expects one argument (the argument is just empty). isVarargsElided = MI->isVariadic(); } else if ((FoundElidedComma || MI->isVariadic()) && (NumActuals+1 == MinArgsExpected || // A(x, ...) -> A(X) (NumActuals == 0 && MinArgsExpected == 2))) {// A(x,...) -> A() // Varargs where the named vararg parameter is missing: OK as extension. // #define A(x, ...) // A("blah") // // If the macro contains the comma pasting extension, the diagnostic // is suppressed; we know we'll get another diagnostic later. if (!MI->hasCommaPasting()) { Diag(Tok, diag::ext_missing_varargs_arg); Diag(MI->getDefinitionLoc(), diag::note_macro_here) << MacroName.getIdentifierInfo(); } // Remember this occurred, allowing us to elide the comma when used for // cases like: // #define A(x, foo...) blah(a, ## foo) // #define B(x, ...) blah(a, ## __VA_ARGS__) // #define C(...) blah(a, ## __VA_ARGS__) // A(x) B(x) C() isVarargsElided = true; } else { // Otherwise, emit the error. Diag(Tok, diag::err_too_few_args_in_macro_invoc); Diag(MI->getDefinitionLoc(), diag::note_macro_here) << MacroName.getIdentifierInfo(); return nullptr; } // Add a marker EOF token to the end of the token list for this argument. SourceLocation EndLoc = Tok.getLocation(); Tok.startToken(); Tok.setKind(tok::eof); Tok.setLocation(EndLoc); Tok.setLength(0); ArgTokens.push_back(Tok); // If we expect two arguments, add both as empty. if (NumActuals == 0 && MinArgsExpected == 2) ArgTokens.push_back(Tok); } else if (NumActuals > MinArgsExpected && !MI->isVariadic()) { // Emit the diagnostic at the macro name in case there is a missing ). // Emitting it at the , could be far away from the macro name. Diag(MacroName, diag::err_too_many_args_in_macro_invoc); Diag(MI->getDefinitionLoc(), diag::note_macro_here) << MacroName.getIdentifierInfo(); return nullptr; } return MacroArgs::create(MI, ArgTokens, isVarargsElided, *this); }