[cfe-dev] [PATCH]: Sema support for C++ classes
Argiris Kirtzidis
akyrtzi at gmail.com
Fri Jun 27 17:23:09 PDT 2008
Chris Lattner wrote:
>
> On Jun 25, 2008, at 9:49 AM, Argiris Kirtzidis wrote:
>
>> Hi,
>>
>> The attached patch adds the missing Sema support for parsing C++
>> classes.
>>
>> About references to instance fields:
>>
>> + // FIXME: Use DeclRefExpr or a new Expr for a direct CXXField
>> reference.
>> + ExprResult ThisExpr = ActOnCXXThis(Loc);
>> + return new MemberExpr(static_cast<Expr*>(ThisExpr.Val),
>> + true, FD, Loc, FD->getType());
>>
>> I'll fix this once Sema support is in place.
>
> Ok! One meta question: the PushDeclContext/pop context logic has to
> keep the CurMethodDecl members up to date, and are somewhat complex.
> Would it be better to change direct accesses to CurMethodDecl to call
> getCurMethodDecl(), which would just look at the current context?
Sounds great! Shall I make a separate commit for this ?
>
> +DIAG(err_member_initialization, ERROR,
> + "'%0' can be initialized only if it is a static const integral
> data member")
>
> How about "can only be initialized if..."
>
>
> +DIAG(err_invalid_this_at_top_level, ERROR,
> + "invalid use of 'this' at top level")
>
> How about "outside of a member function"? It would also subsume
> err_invalid_this_in_non_member_func
Ok.
>
> Are methods in C++ officially known as "member functions" or "methods"?
The standard uses "member functions".
>
>
> +++ lib/Sema/Sema.h (working copy)
>
> + /// CXXFieldCollector - Used to keep track of CXXFieldDecls during
> parsing of
> + /// C++ classes.
> + class {
>
> Instead of nesting this inside the sema class, please pull this out to
> its own header (or put in SemaUtil.h). The sema class is already very
> large, which means it is hard to understand "at a glance". Also, it
> is probably best for Sema to have a pointer (e.g. an OwningPtr) to the
> instance instead of having it inline. This allows it to be lazily
> created and helps keep sizeof(Sema) reasonable.
>
>
> + llvm::SmallVector<CXXFieldDecl*, 32> Fields;
> + llvm::SmallVector<size_t, 4> FieldCount;
>
> Please comment what these are and what invariants hold.
>
> + /// getNumField - The number of fields added to the currently
> parsed class.
> + size_t getNumField() const { return FieldCount.back(); }
>
> "getNumFields"?
>
>
> + /// StartClass - Called by Sema::ActOnFinishCXXClassDef.
> + void FinishClass() {
>
> plz update comment.
>
>
> + assert(isa<CXXMethodDecl>(FD) || CurFunctionDecl == 0
> + && "Confused parsing.");
>
> You need parens here.
Ok to all.
>
>
> + if (getLangOptions().CPlusPlus)
> + New = CXXRecordDecl::Create(Context, Kind, CurContext, Loc,
> Name, 0);
> + else
> + New = RecordDecl::Create(Context, Kind, CurContext, Loc, Name, 0);
>
>
> Is it hopeless to use the "light weight recorddecl" for "simple enough
> structs" even in C++?
>
> + if (getLangOptions().CPlusPlus) {
> + NewFD = CXXFieldDecl::Create(Context,
> cast<CXXRecordDecl>(CurContext),
> + Loc, II, T, BitWidth);
> + PushOnScopeChains(NewFD, S);
> + }
> + else
> + NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth);
>
> likewise.
>
Using plain FieldDecls for simple structs should be easy, I'm not sure
about CXX/RecordDecl.
Can we add this as is so we have the functionality and tests in, and
later look for ways to optimize it ?
>
>
> +++ lib/Sema/SemaExprCXX.cpp (working copy)
> @@ -49,3 +49,21 @@
> +
> +Action::ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
> + /// C++ 9.3.2: In the body of a non-static member function, the
> keyword this is
>
> 80 col violation
>
>
> +++ lib/Sema/SemaExpr.cpp (working copy)
>
> + if (MD->isStatic())
> + // "invalid use of member 'x' in static member function"
> + return Diag(Loc,
> diag::err_invalid_member_use_in_static_method, FD->getName());
> + if (cast<CXXRecordDecl>(MD->getParent()) != FD->getParent())
>
> likewise.
>
> ===================================================================
> --- lib/Sema/SemaDeclCXX.cpp (revision 52718)
> +++ lib/Sema/SemaDeclCXX.cpp (working copy)
>
> in Sema::ActOnStartCXXClassDef and:
>
> +void Sema::ActOnFinishCXXClassDef(DeclTy *D,SourceLocation RBrace) {
> + Decl *Dcl = static_cast<Decl *>(D);
> + CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(Dcl);
> + assert(RD && "Invalid parameter, expected CXXRecordDecl");
> + CXXFieldCollector.FinishClass();
> + PopDeclContext();
> +}
>
> Instead of using dyn_cast_or_null + assert(not null), just use cast<>
Ok to all.
>
>
> +Sema::DeclTy *
> +Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
> Declarator &D,
>
>
> + assert(II && "No identifier ?");
>
> does this abort on unnamed bitfields like "int : 4;" ?
This requires changes to the parser too. Can we fix it after the patch
goes in so I can make one "unified" Parser+Sema+test commit, specific to
this case ?
>
>
> + CXXClassMemberWrapper MW(Member);
> + MW.setAccess(AS);
> +
>
> What does this do? I had to look this up, it is somewhat strange. At
> the least, how about:
>
> // What this does and why we can't just call Member->setAccess(..)
> CXXClassMemberWrapper(Member).setAccess(AS);
Ok.
-Argiris
More information about the cfe-dev
mailing list