[cfe-commits] r114929 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Sema/Sema.h lib/AST/DeclCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp
Douglas Gregor
dgregor at apple.com
Mon Sep 27 17:00:00 PDT 2010
Author: dgregor
Date: Mon Sep 27 19:00:00 2010
New Revision: 114929
URL: http://llvm.org/viewvc/llvm-project?rev=114929&view=rev
Log:
Centralize the management of CXXRecordDecl::DefinitionData's
HasTrivialConstructor, HasTrivialCopyConstructor,
HasTrivialCopyAssignment, and HasTrivialDestructor bits in
CXXRecordDecl's methods. This completes all but the Abstract bit and
the set of conversion functions, both of which will require a bit of
extra work. The majority of <rdar://problem/8459981> is now
implemented (but not all of it).
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Sep 27 19:00:00 2010
@@ -688,10 +688,6 @@
/// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
bool isAggregate() const { return data().Aggregate; }
- /// setMethodAsVirtual - Make input method virtual and set the necesssary
- /// special function bits and other bits accordingly.
- void setMethodAsVirtual(FunctionDecl *Method);
-
/// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
/// that is an aggregate that has no non-static non-POD data members, no
/// reference data members, no user-defined copy assignment operator and no
@@ -719,42 +715,22 @@
// (C++ [class.ctor]p5)
bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
- // setHasTrivialConstructor - Set whether this class has a trivial constructor
- // (C++ [class.ctor]p5)
- void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; }
-
// hasTrivialCopyConstructor - Whether this class has a trivial copy
// constructor (C++ [class.copy]p6)
bool hasTrivialCopyConstructor() const {
return data().HasTrivialCopyConstructor;
}
- // setHasTrivialCopyConstructor - Set whether this class has a trivial
- // copy constructor (C++ [class.copy]p6)
- void setHasTrivialCopyConstructor(bool TC) {
- data().HasTrivialCopyConstructor = TC;
- }
-
// hasTrivialCopyAssignment - Whether this class has a trivial copy
// assignment operator (C++ [class.copy]p11)
bool hasTrivialCopyAssignment() const {
return data().HasTrivialCopyAssignment;
}
- // setHasTrivialCopyAssignment - Set whether this class has a
- // trivial copy assignment operator (C++ [class.copy]p11)
- void setHasTrivialCopyAssignment(bool TC) {
- data().HasTrivialCopyAssignment = TC;
- }
-
// hasTrivialDestructor - Whether this class has a trivial destructor
// (C++ [class.dtor]p3)
bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
- // setHasTrivialDestructor - Set whether this class has a trivial destructor
- // (C++ [class.dtor]p3)
- void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; }
-
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Sep 27 19:00:00 2010
@@ -2584,13 +2584,6 @@
bool Virtual, AccessSpecifier Access,
TypeSourceInfo *TInfo);
- /// SetClassDeclAttributesFromBase - Copies class decl traits
- /// (such as whether the class has a trivial constructor,
- /// trivial destructor etc) from the given base class.
- void SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
- const CXXRecordDecl *BaseClass,
- bool BaseIsVirtual);
-
BaseResult ActOnBaseSpecifier(Decl *classdecl,
SourceRange SpecifierRange,
bool Virtual, AccessSpecifier Access,
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Sep 27 19:00:00 2010
@@ -134,7 +134,45 @@
// T is a class type, but not a union type, with ... no virtual base
// classes
data().Empty = false;
+
+ // C++ [class.ctor]p5:
+ // A constructor is trivial if its class has no virtual base classes.
+ data().HasTrivialConstructor = false;
+
+ // C++ [class.copy]p6:
+ // A copy constructor is trivial if its class has no virtual base
+ // classes.
+ data().HasTrivialCopyConstructor = false;
+
+ // C++ [class.copy]p11:
+ // A copy assignment operator is trivial if its class has no virtual
+ // base classes.
+ data().HasTrivialCopyAssignment = false;
+ } else {
+ // C++ [class.ctor]p5:
+ // A constructor is trivial if all the direct base classes of its
+ // class have trivial constructors.
+ if (!BaseClassDecl->hasTrivialConstructor())
+ data().HasTrivialConstructor = false;
+
+ // C++ [class.copy]p6:
+ // A copy constructor is trivial if all the direct base classes of its
+ // class have trivial copy constructors.
+ if (!BaseClassDecl->hasTrivialCopyConstructor())
+ data().HasTrivialCopyConstructor = false;
+
+ // C++ [class.copy]p11:
+ // A copy assignment operator is trivial if all the direct base classes
+ // of its class have trivial copy assignment operators.
+ if (!BaseClassDecl->hasTrivialCopyAssignment())
+ data().HasTrivialCopyAssignment = false;
}
+
+ // C++ [class.ctor]p3:
+ // A destructor is trivial if all the direct base classes of its class
+ // have trivial destructors.
+ if (!BaseClassDecl->hasTrivialDestructor())
+ data().HasTrivialDestructor = false;
}
if (VBases.empty())
@@ -309,6 +347,12 @@
// A class that declares or inherits a virtual function is called a
// polymorphic class.
data().Polymorphic = true;
+
+ // None of the special member functions are trivial.
+ data().HasTrivialConstructor = false;
+ data().HasTrivialCopyConstructor = false;
+ data().HasTrivialCopyAssignment = false;
+ // FIXME: Destructor?
}
}
@@ -384,6 +428,13 @@
// destructor.
data().PlainOldData = false;
+ // C++ [class.dtor]p3:
+ // A destructor is trivial if it is an implicitly-declared destructor and
+ // [...].
+ //
+ // FIXME: C++0x: don't do this for "= default" destructors
+ data().HasTrivialDestructor = false;
+
return;
}
@@ -453,6 +504,22 @@
QualType T = Context.getBaseElementType(Field->getType());
if (!T->isPODType())
data().PlainOldData = false;
+ if (T->isReferenceType())
+ data().HasTrivialConstructor = false;
+
+ if (const RecordType *RecordTy = T->getAs<RecordType>()) {
+ CXXRecordDecl* FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl());
+ if (FieldRec->getDefinition()) {
+ if (!FieldRec->hasTrivialConstructor())
+ data().HasTrivialConstructor = false;
+ if (!FieldRec->hasTrivialCopyConstructor())
+ data().HasTrivialCopyConstructor = false;
+ if (!FieldRec->hasTrivialCopyAssignment())
+ data().HasTrivialCopyAssignment = false;
+ if (!FieldRec->hasTrivialDestructor())
+ data().HasTrivialDestructor = false;
+ }
+ }
// If this is not a zero-length bit-field, then the class is not empty.
if (data().Empty) {
@@ -649,13 +716,6 @@
llvm_unreachable("conversion not found in set!");
}
-void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) {
- Method->setVirtualAsWritten(true);
- setHasTrivialConstructor(false);
- setHasTrivialCopyConstructor(false);
- setHasTrivialCopyAssignment(false);
-}
-
CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Sep 27 19:00:00 2010
@@ -3425,8 +3425,7 @@
<< FixItHint::CreateRemoval(D.getDeclSpec().getVirtualSpecLoc());
} else {
// Okay: Add virtual to the method.
- CXXRecordDecl *CurClass = cast<CXXRecordDecl>(DC);
- CurClass->setMethodAsVirtual(NewFD);
+ NewFD->setVirtualAsWritten(true);
}
}
@@ -3927,11 +3926,6 @@
return NewFD->setInvalidDecl();
}
}
-
- // C++ [class.dtor]p3: A destructor is trivial if it is an implicitly-
- // declared destructor.
- // FIXME: C++0x: don't do this for "= default" destructors
- Record->setHasTrivialDestructor(false);
} else if (CXXConversionDecl *Conversion
= dyn_cast<CXXConversionDecl>(NewFD)) {
ActOnConversionDeclarator(Conversion);
@@ -6185,23 +6179,9 @@
}
if (!InvalidDecl && getLangOptions().CPlusPlus) {
- CXXRecordDecl* CXXRecord = cast<CXXRecordDecl>(Record);
-
- if (T->isReferenceType())
- CXXRecord->setHasTrivialConstructor(false);
-
if (const RecordType *RT = EltTy->getAs<RecordType>()) {
CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
if (RDecl->getDefinition()) {
- if (!RDecl->hasTrivialConstructor())
- CXXRecord->setHasTrivialConstructor(false);
- if (!RDecl->hasTrivialCopyConstructor())
- CXXRecord->setHasTrivialCopyConstructor(false);
- if (!RDecl->hasTrivialCopyAssignment())
- CXXRecord->setHasTrivialCopyAssignment(false);
- if (!RDecl->hasTrivialDestructor())
- CXXRecord->setHasTrivialDestructor(false);
-
// C++ 9.5p1: An object of a class with a non-trivial
// constructor, a non-trivial copy constructor, a non-trivial
// destructor, or a non-trivial copy assignment operator
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Sep 27 19:00:00 2010
@@ -502,8 +502,6 @@
return 0;
}
- SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual);
-
if (BaseDecl->isInvalidDecl())
Class->setInvalidDecl();
@@ -513,49 +511,6 @@
Access, TInfo);
}
-void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
- const CXXRecordDecl *BaseClass,
- bool BaseIsVirtual) {
- if (BaseIsVirtual) {
- // C++ [class.ctor]p5:
- // A constructor is trivial if its class has no virtual base classes.
- Class->setHasTrivialConstructor(false);
-
- // C++ [class.copy]p6:
- // A copy constructor is trivial if its class has no virtual base classes.
- Class->setHasTrivialCopyConstructor(false);
-
- // C++ [class.copy]p11:
- // A copy assignment operator is trivial if its class has no virtual
- // base classes.
- Class->setHasTrivialCopyAssignment(false);
- } else {
- // C++ [class.ctor]p5:
- // A constructor is trivial if all the direct base classes of its
- // class have trivial constructors.
- if (!BaseClass->hasTrivialConstructor())
- Class->setHasTrivialConstructor(false);
-
- // C++ [class.copy]p6:
- // A copy constructor is trivial if all the direct base classes of its
- // class have trivial copy constructors.
- if (!BaseClass->hasTrivialCopyConstructor())
- Class->setHasTrivialCopyConstructor(false);
-
- // C++ [class.copy]p11:
- // A copy assignment operator is trivial if all the direct base classes
- // of its class have trivial copy assignment operators.
- if (!BaseClass->hasTrivialCopyAssignment())
- Class->setHasTrivialCopyAssignment(false);
- }
-
- // C++ [class.ctor]p3:
- // A destructor is trivial if all the direct base classes of its class
- // have trivial destructors.
- if (!BaseClass->hasTrivialDestructor())
- Class->setHasTrivialDestructor(false);
-}
-
/// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is
/// one entry in the base class list of a class specifier, for
/// example:
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Sep 27 19:00:00 2010
@@ -1091,13 +1091,6 @@
Base = Pattern->bases_begin(), BaseEnd = Pattern->bases_end();
Base != BaseEnd; ++Base) {
if (!Base->getType()->isDependentType()) {
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-
- // Make sure to set the attributes from the base.
- SetClassDeclAttributesFromBase(Instantiation, BaseDecl,
- Base->isVirtual());
-
InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(*Base));
continue;
}
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=114929&r1=114928&r2=114929&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Sep 27 19:00:00 2010
@@ -1996,10 +1996,9 @@
if (InitFunctionInstantiation(New, Tmpl))
return true;
- CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
New->setAccess(Tmpl->getAccess());
if (Tmpl->isVirtualAsWritten())
- Record->setMethodAsVirtual(New);
+ New->setVirtualAsWritten(true);
// FIXME: attributes
// FIXME: New needs a pointer to Tmpl
More information about the cfe-commits
mailing list