rjmccall added inline comments.

================
Comment at: lib/Sema/SemaDecl.cpp:10286
+          // these variables must be a compile time constant.
+          VDecl->getType().getAddressSpace() == LangAS::opencl_constant)
         CheckForConstantInitializer(Init, DclT);
----------------
Anastasia wrote:
> yaxunl wrote:
> > rjmccall wrote:
> > > yaxunl wrote:
> > > > Anastasia wrote:
> > > > > yaxunl wrote:
> > > > > > rjmccall wrote:
> > > > > > > yaxunl wrote:
> > > > > > > > rjmccall wrote:
> > > > > > > > > Should this rule apply even in C++ mode?  I can't remember if 
> > > > > > > > > there are any OpenCL/C++ hybrids.
> > > > > > > > No. This rule (static local variable needs to be initialised 
> > > > > > > > with compile-time constant) only applies to C and OpenCL. 
> > > > > > > > In C++ static local variable can be initialised with 
> > > > > > > > non-compile-time constant, in which case Clang will emit atomic 
> > > > > > > > instructions to make sure it is only initialised once.
> > > > > > > > 
> > > > > > > > Currently OpenCL 2.2 defines OpenCL C++ but clang does not 
> > > > > > > > support it.
> > > > > > > Yes, I understand that C++ generally allows static locals to be 
> > > > > > > lazily initialized, and that that rule would (probably) still 
> > > > > > > apply to ordinary static locals in OpenCL C++.  However, I would 
> > > > > > > expect that OpenCL C++ rule is that __constant local variables 
> > > > > > > still need to be statically initialized, because there's no 
> > > > > > > plausible way in the OpenCL implementation model to actually put 
> > > > > > > lazily-initialized variables in the constant address space.  
> > > > > > > Assuming that's correct, then I would recommend reworking this 
> > > > > > > whole chain of conditions to:
> > > > > > > 
> > > > > > >   // Don't check the initializer if the declaration is malformed.
> > > > > > >   if (VDecl->isInvalidDecl()) {
> > > > > > >     // do nothing
> > > > > > > 
> > > > > > >   // OpenCL __constant locals must be constant-initialized, even 
> > > > > > > in OpenCL C++.
> > > > > > >   } else if (VDecl->getType().getAddressSpace() == 
> > > > > > > LangAS::opencl_constant) {
> > > > > > >     CheckForConstantInitializer(Init, DclT);
> > > > > > > 
> > > > > > >   // Otherwise, C++ does not restrict the initializer.
> > > > > > >   } else if (getLangOpts().CPlusPlus) {
> > > > > > >     // do nothing
> > > > > > > 
> > > > > > >   // C99 6.7.8p4: All the expressions in an initializer for an 
> > > > > > > object that has
> > > > > > >   // static storage duration shall be constant expressions or 
> > > > > > > string literals.
> > > > > > >   } else if (VDecl->getStorageClass() == SC_Static) {
> > > > > > >     CheckForConstantInitializer(Init, DclT);
> > > > > > > 
> > > > > > >   // C89 is stricter than C99 for aggregate initializers.
> > > > > > >   // C89 6.5.7p3: All the expressions [...] in an initializer list
> > > > > > >   // for an object that has aggregate or union type shall be
> > > > > > >   // constant expressions.
> > > > > > >   } else if (!getLangOpts().C99 && 
> > > > > > > VDecl->getType()->isAggregateType() && isa<InitListExpr>(Init)) {
> > > > > > >     Expr *Culprit;
> > > > > > >     if (!Init->isConstantInitializer(Context, false, &Culprit)) {
> > > > > > >       ...
> > > > > > >     }
> > > > > > >   }
> > > > > > Agree that even OpenCL C++ is unable to lazy initialise 
> > > > > > function-scope var in constant addr space. Will do.
> > > > > I think the original way would be much simpler to read and understand 
> > > > > though.
> > > > > 
> > > > > To be honest I wouldn't complicate things now for the feature we 
> > > > > don't support. I feel OpenCL C++ should be represented as a separate 
> > > > > LangOpt since there are some places that will require special 
> > > > > handling due to deviation from C++. I would rather extend things 
> > > > > later in more systematic way.
> > > > I will delete the comment about OpenCL C++ when committing.
> > > I disagree.  Simple chains like this are almost always superior to 
> > > building up complex logical conditions: the priorities between conditions 
> > > are clearer (such as the interaction between __constant and C++ here), 
> > > each condition can be conveniently documented without having to add 
> > > comments to the middle of an expression, and there's less need to build 
> > > up (A && !B) conditions just to make sure that cases are routed to the 
> > > right place.  If the body of a clause is complex, it's usually a good 
> > > idea to extract it into a separate function anyway, as has already been 
> > > done here with CheckForConstantInitializer.
> > > 
> > > Deleting the comment about OpenCL C++ seems silly.  The comment is 
> > > correct and explains why the clauses need to be ordered the way they are, 
> > > and someone implementing OpenCL C++ support later will not think to add 
> > > it back.
> > > 
> > > Please trust me that you would not want to use a different LangOpt for 
> > > OpenCL C++.  OpenCL C++ may feel a little different from normal C++ to a 
> > > user, but for the compiler its deviations are tiny compared to the number 
> > > of ways in which C++ deviates from C.  The major C++ features that really 
> > > cut across the frontend are all still there: templates, references, type 
> > > members, function overloading, operator overloading, totally different 
> > > lookup rules, etc.
> > I double checked OpenCL 2.2 C++ language spec and did some experiment with 
> > the khronos implementation:
> > 
> > https://www.khronos.org/registry/OpenCL/specs/opencl-2.2-cplusplus.pdf
> > 
> > https://github.com/KhronosGroup/libclcxx
> > 
> > I think you are right about the constant address space in OpenCL C++. 
> > Although OpenCL C++ uses class templates to implement address space, it 
> > does use `__constant` to implement constant class template internally, and 
> > supports `__constant` address space qualifier. Therefore the comment about 
> > OpenCL C++ should be correct.
> > 
> Btw, it does seem to be adding `OpenCLCPlusPlus` to `LangOpts`.
Well, they can do whatever they want in a fork.  As long as they're also 
setting CPlusPlus it's not a big deal.  But I suspect that overall it's quite a 
bit like Objective-C++, where it makes a lot more sense to keep them as 
separate flags and just occasionally add C++-specific code to an ObjC code path 
or vice-versa.


Repository:
  rL LLVM

https://reviews.llvm.org/D32977



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to