[cfe-commits] r75649 - in /cfe/trunk: include/clang/Parse/Action.h lib/AST/DeclCXX.cpp lib/Parse/ParseCXXInlineMethods.cpp lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp
Fariborz Jahanian
fjahanian at apple.com
Tue Jul 14 11:24:37 PDT 2009
Author: fjahanian
Date: Tue Jul 14 13:24:21 2009
New Revision: 75649
URL: http://llvm.org/viewvc/llvm-project?rev=75649&view=rev
Log:
Patch to build AST for ctor's initializer list according to
semantics of order of construction [class.init].
Modified:
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=75649&r1=75648&r2=75649&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Jul 14 13:24:21 2009
@@ -1232,6 +1232,8 @@
SourceLocation ColonLoc,
MemInitTy **MemInits, unsigned NumMemInits){
}
+
+ virtual void ActOnDefaultInitializers(DeclPtrTy ConstructorDecl) {}
/// ActOnFinishCXXMemberSpecification - Invoked after all member declarators
/// are parsed but *before* parsing of inline method definitions.
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=75649&r1=75648&r2=75649&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Jul 14 13:24:21 2009
@@ -482,12 +482,81 @@
ASTContext &C,
CXXBaseOrMemberInitializer **Initializers,
unsigned NumInitializers) {
+ // We need to build the initializer AST according to order of construction
+ // and not what user specified in the Initializers list.
+ // FIXME. We probably don't need this. But it is cleaner.
+ CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext());
+ llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit;
+ // Push virtual bases before others.
+ for (CXXRecordDecl::base_class_iterator VBase =
+ ClassDecl->vbases_begin(),
+ E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
+ const Type * T = VBase->getType()->getAsRecordType();
+ unsigned int i = 0;
+ for (i = 0; i < NumInitializers; i++) {
+ CXXBaseOrMemberInitializer *Member = Initializers[i];
+ if (Member->isBaseInitializer() &&
+ Member->getBaseClass() == T) {
+ AllToInit.push_back(Member);
+ break;
+ }
+ }
+ if (i == NumInitializers) {
+ CXXBaseOrMemberInitializer *Member =
+ new CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,SourceLocation());
+ AllToInit.push_back(Member);
+ }
+ }
+ for (CXXRecordDecl::base_class_iterator Base =
+ ClassDecl->bases_begin(),
+ E = ClassDecl->bases_end(); Base != E; ++Base) {
+ // Virtuals are in the virtual base list and already constructed.
+ if (Base->isVirtual())
+ continue;
+ const Type * T = Base->getType()->getAsRecordType();
+ unsigned int i = 0;
+ for (i = 0; i < NumInitializers; i++) {
+ CXXBaseOrMemberInitializer *Member = Initializers[i];
+ if (Member->isBaseInitializer() && Member->getBaseClass() == T) {
+ AllToInit.push_back(Member);
+ break;
+ }
+ }
+ if (i == NumInitializers) {
+ CXXBaseOrMemberInitializer *Member =
+ new CXXBaseOrMemberInitializer(Base->getType(), 0, 0, SourceLocation());
+ AllToInit.push_back(Member);
+ }
+ }
+ // non-static data members.
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ E = ClassDecl->field_end(); Field != E; ++Field) {
+ unsigned int i = 0;
+ for (i = 0; i < NumInitializers; i++) {
+ CXXBaseOrMemberInitializer *Member = Initializers[i];
+ if (Member->isMemberInitializer() && Member->getMember() == (*Field)) {
+ AllToInit.push_back(Member);
+ break;
+ }
+ }
+ if (i == NumInitializers) {
+ // FIXME. What do we do with arrays?
+ QualType FieldType = C.getCanonicalType((*Field)->getType());
+ if (FieldType->getAsRecordType()) {
+ CXXBaseOrMemberInitializer *Member =
+ new CXXBaseOrMemberInitializer((*Field), 0, 0, SourceLocation());
+ AllToInit.push_back(Member);
+ }
+ }
+ }
+
+ NumInitializers = AllToInit.size();
if (NumInitializers > 0) {
NumBaseOrMemberInitializers = NumInitializers;
BaseOrMemberInitializers =
new (C) CXXBaseOrMemberInitializer*[NumInitializers];
for (unsigned Idx = 0; Idx < NumInitializers; ++Idx)
- BaseOrMemberInitializers[Idx] = Initializers[Idx];
+ BaseOrMemberInitializers[Idx] = AllToInit[Idx];
}
}
Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=75649&r1=75648&r2=75649&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Tue Jul 14 13:24:21 2009
@@ -171,6 +171,10 @@
}
if (Tok.is(tok::colon))
ParseConstructorInitializer(LM.D);
+ else {
+ Actions.ActOnDefaultInitializers(LM.D);
+ }
+
// FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'??
ParseFunctionStatementBody(LM.D);
}
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=75649&r1=75648&r2=75649&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Jul 14 13:24:21 2009
@@ -1468,6 +1468,7 @@
SourceLocation MemberLoc,
IdentifierInfo &Member,
DeclPtrTy ImplDecl);
+ virtual void ActOnDefaultInitializers(DeclPtrTy ConstructorDecl);
bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
FunctionDecl *FDecl,
const FunctionProtoType *Proto,
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=75649&r1=75648&r2=75649&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Jul 14 13:24:21 2009
@@ -902,6 +902,17 @@
}
}
+void Sema::ActOnDefaultInitializers(DeclPtrTy ConstructorDecl) {
+ if (!ConstructorDecl)
+ return;
+
+ if (CXXConstructorDecl *Constructor
+ = dyn_cast<CXXConstructorDecl>(ConstructorDecl.getAs<Decl>()))
+ Constructor->setBaseOrMemberInitializers(Context,
+ (CXXBaseOrMemberInitializer **)0, 0);
+
+}
+
namespace {
/// PureVirtualMethodCollector - traverses a class and its superclasses
/// and determines if it has any pure virtual methods.
More information about the cfe-commits
mailing list