Changeset View
Standalone View
clang/lib/Sema/SemaLambda.cpp
Show First 20 Lines • Show All 984 Lines • ▼ Show 20 Lines | void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, | ||||
// code_seg attribute on lambda apply to the method. | // code_seg attribute on lambda apply to the method. | ||||
if (Attr *A = getImplicitCodeSegOrSectionAttrForFunction(Method, /*IsDefinition=*/true)) | if (Attr *A = getImplicitCodeSegOrSectionAttrForFunction(Method, /*IsDefinition=*/true)) | ||||
Method->addAttr(A); | Method->addAttr(A); | ||||
// Attributes on the lambda apply to the method. | // Attributes on the lambda apply to the method. | ||||
ProcessDeclAttributes(CurScope, Method, ParamInfo); | ProcessDeclAttributes(CurScope, Method, ParamInfo); | ||||
// CUDA lambdas get implicit attributes based on the scope in which they're | // CUDA lambdas get implicit host and device attributes. | ||||
// declared. | |||||
if (getLangOpts().CUDA) | if (getLangOpts().CUDA) | ||||
CUDASetLambdaAttrs(Method); | CUDASetLambdaAttrs(Method); | ||||
// Number the lambda for linkage purposes if necessary. | // Number the lambda for linkage purposes if necessary. | ||||
handleLambdaNumbering(Class, Method); | handleLambdaNumbering(Class, Method); | ||||
// Introduce the function call operator as the current declaration context. | // Introduce the function call operator as the current declaration context. | ||||
PushDeclContext(CurScope, Method); | PushDeclContext(CurScope, Method); | ||||
▲ Show 20 Lines • Show All 772 Lines • ▼ Show 20 Lines | for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) { | ||||
// FIXME: Skip this capture if the capture is not used, the initializer | // FIXME: Skip this capture if the capture is not used, the initializer | ||||
// has no side-effects, the type of the capture is trivial, and the | // has no side-effects, the type of the capture is trivial, and the | ||||
// lambda is not externally visible. | // lambda is not externally visible. | ||||
// Add a FieldDecl for the capture and form its initializer. | // Add a FieldDecl for the capture and form its initializer. | ||||
BuildCaptureField(Class, From); | BuildCaptureField(Class, From); | ||||
Captures.push_back(Capture); | Captures.push_back(Capture); | ||||
CaptureInits.push_back(Init.get()); | CaptureInits.push_back(Init.get()); | ||||
if (LangOpts.CUDA) | |||||
tra: I would expect Sema-level diags to be produced during both host and device compilation. Some of… | |||||
A host device function could be emitted in both host and device compilation. The way the deferred diags works is that they are only emitted when the function is sure to be emitted in a specific compilation. In host compilation, when a host device function is sure to be emitted, it is emitted as host function, therefore diags for host compilation and only diags for host compilation should be emitted. The same with device compilation. This makes sense since we do not know if a host device function will be emitted in device compilation when we are doing host compilation, since to do that we have to go through the whole device compilation whereas currently device compilation and host compilation are separate process. That said, when we emit diags for captures by reference, we should only emit them when the lambdas are emitted as device functions. When they are emitted as host functions in host compilation, these captures are valid and should not be diagnosed. yaxunl: A host device function could be emitted in both host and device compilation. The way the… | |||||
HD lambda capturing something that's side-specific is similar to HD function calling side-specific function. I still think that the general principle applies to both sides of the compilation. We may be saved by the fact that functions seem to be the only things that are truly side-specific and wrong-side access will already produce postponed diagnostics. For variables we'll end up capturing shadows, which is in the gray area -- we're allowed to use pointers & sizeof(), but not the non-const values. Perhaps this condition check should be folded into the CUDACheckLambdaCapture and add few comments about the reasons for particular OK/not-OK choices we make there. tra: HD lambda capturing something that's side-specific is similar to HD function calling side… | |||||
CUDACheckLambdaCapture(CallOperator, From); | |||||
} | } | ||||
Class->setCaptures(Captures); | Class->setCaptures(Captures); | ||||
// C++11 [expr.prim.lambda]p6: | // C++11 [expr.prim.lambda]p6: | ||||
// The closure type for a lambda-expression with no lambda-capture | // The closure type for a lambda-expression with no lambda-capture | ||||
// has a public non-virtual non-explicit const conversion function | // has a public non-virtual non-explicit const conversion function | ||||
// to pointer to function having the same parameter and return | // to pointer to function having the same parameter and return | ||||
▲ Show 20 Lines • Show All 148 Lines • Show Last 20 Lines |
I would expect Sema-level diags to be produced during both host and device compilation. Some of the diags for HD may need to be postponed until after things have been CodeGen'ed, but the checks should happen nevertheless.