summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp198
1 files changed, 138 insertions, 60 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp b/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp
index 0646499..a17abdd 100644
--- a/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp
@@ -10,9 +10,9 @@
// This file implements the C++ related Decl classes.
//
//===----------------------------------------------------------------------===//
-
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclTemplate.h"
@@ -35,6 +35,17 @@ AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (Mem) AccessSpecDecl(EmptyShell());
}
+void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const {
+ ExternalASTSource *Source = C.getExternalSource();
+ assert(Impl.Decls.isLazy() && "getFromExternalSource for non-lazy set");
+ assert(Source && "getFromExternalSource with no external source");
+
+ for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I)
+ I.setDecl(cast<NamedDecl>(Source->GetExternalDecl(
+ reinterpret_cast<uintptr_t>(I.getDecl()) >> 2)));
+ Impl.Decls.setLazy(false);
+}
+
CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
: UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0),
Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
@@ -60,9 +71,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
ImplicitCopyAssignmentHasConstParam(true),
HasDeclaredCopyConstructorWithConstParam(false),
HasDeclaredCopyAssignmentWithConstParam(false),
- FailedImplicitMoveConstructor(false), FailedImplicitMoveAssignment(false),
IsLambda(false), NumBases(0), NumVBases(0), Bases(), VBases(),
- Definition(D), FirstFriend(0) {
+ Definition(D), FirstFriend() {
}
CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const {
@@ -97,12 +107,17 @@ CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
TypeSourceInfo *Info, SourceLocation Loc,
- bool Dependent) {
+ bool Dependent, bool IsGeneric,
+ LambdaCaptureDefault CaptureDefault) {
CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc,
0, 0);
R->IsBeingDefined = true;
- R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info, Dependent);
+ R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info,
+ Dependent,
+ IsGeneric,
+ CaptureDefault);
R->MayHaveOutOfDateDef = false;
+ R->setImplicit(true);
C.getTypeDeclType(R, /*PrevDecl=*/0);
return R;
}
@@ -552,18 +567,16 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (Conversion->getPrimaryTemplate()) {
// We don't record specializations.
- } else if (FunTmpl) {
- if (FunTmpl->getPreviousDecl())
- data().Conversions.replace(FunTmpl->getPreviousDecl(),
- FunTmpl, AS);
- else
- data().Conversions.addDecl(getASTContext(), FunTmpl, AS);
} else {
- if (Conversion->getPreviousDecl())
- data().Conversions.replace(Conversion->getPreviousDecl(),
- Conversion, AS);
+ ASTContext &Ctx = getASTContext();
+ ASTUnresolvedSet &Conversions = data().Conversions.get(Ctx);
+ NamedDecl *Primary =
+ FunTmpl ? cast<NamedDecl>(FunTmpl) : cast<NamedDecl>(Conversion);
+ if (Primary->getPreviousDecl())
+ Conversions.replace(cast<NamedDecl>(Primary->getPreviousDecl()),
+ Primary, AS);
else
- data().Conversions.addDecl(getASTContext(), Conversion, AS);
+ Conversions.addDecl(Ctx, Primary, AS);
}
}
@@ -662,7 +675,7 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (!Context.getLangOpts().ObjCAutoRefCount ||
T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone)
setHasObjectMember(true);
- } else if (!T.isPODType(Context))
+ } else if (!T.isCXX98PODType(Context))
data().PlainOldData = false;
if (T->isReferenceType()) {
@@ -712,6 +725,13 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (FieldRec->getDefinition()) {
addedClassSubobject(FieldRec);
+ // We may need to perform overload resolution to determine whether a
+ // field can be moved if it's const or volatile qualified.
+ if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) {
+ data().NeedOverloadResolutionForMoveConstructor = true;
+ data().NeedOverloadResolutionForMoveAssignment = true;
+ }
+
// C++11 [class.ctor]p5, C++11 [class.copy]p11:
// A defaulted [special member] for a class X is defined as
// deleted if:
@@ -880,10 +900,13 @@ void CXXRecordDecl::addedMember(Decl *D) {
}
// Handle using declarations of conversion functions.
- if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(D))
+ if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(D)) {
if (Shadow->getDeclName().getNameKind()
- == DeclarationName::CXXConversionFunctionName)
- data().Conversions.addDecl(getASTContext(), Shadow, Shadow->getAccess());
+ == DeclarationName::CXXConversionFunctionName) {
+ ASTContext &Ctx = getASTContext();
+ data().Conversions.get(Ctx).addDecl(Ctx, Shadow, Shadow->getAccess());
+ }
+ }
}
void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) {
@@ -929,6 +952,43 @@ bool CXXRecordDecl::isCLike() const {
return isPOD() && data().HasOnlyCMembers;
}
+
+bool CXXRecordDecl::isGenericLambda() const {
+ if (!isLambda()) return false;
+ return getLambdaData().IsGenericLambda;
+}
+
+CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const {
+ if (!isLambda()) return 0;
+ DeclarationName Name =
+ getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
+ DeclContext::lookup_const_result Calls = lookup(Name);
+
+ assert(!Calls.empty() && "Missing lambda call operator!");
+ assert(Calls.size() == 1 && "More than one lambda call operator!");
+
+ NamedDecl *CallOp = Calls.front();
+ if (FunctionTemplateDecl *CallOpTmpl =
+ dyn_cast<FunctionTemplateDecl>(CallOp))
+ return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl());
+
+ return cast<CXXMethodDecl>(CallOp);
+}
+
+CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const {
+ if (!isLambda()) return 0;
+ DeclarationName Name =
+ &getASTContext().Idents.get(getLambdaStaticInvokerName());
+ DeclContext::lookup_const_result Invoker = lookup(Name);
+ if (Invoker.empty()) return 0;
+ assert(Invoker.size() == 1 && "More than one static invoker operator!");
+ NamedDecl *InvokerFun = Invoker.front();
+ if (FunctionTemplateDecl *InvokerTemplate =
+ dyn_cast<FunctionTemplateDecl>(InvokerFun))
+ return cast<CXXMethodDecl>(InvokerTemplate->getTemplatedDecl());
+
+ return cast<CXXMethodDecl>(InvokerFun);
+}
void CXXRecordDecl::getCaptureFields(
llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
@@ -940,15 +1000,22 @@ void CXXRecordDecl::getCaptureFields(
RecordDecl::field_iterator Field = field_begin();
for (LambdaExpr::Capture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
C != CEnd; ++C, ++Field) {
- if (C->capturesThis()) {
+ if (C->capturesThis())
ThisCapture = *Field;
- continue;
- }
-
- Captures[C->getCapturedVar()] = *Field;
+ else if (C->capturesVariable())
+ Captures[C->getCapturedVar()] = *Field;
}
+ assert(Field == field_end());
}
+TemplateParameterList *
+CXXRecordDecl::getGenericLambdaTemplateParameterList() const {
+ if (!isLambda()) return 0;
+ CXXMethodDecl *CallOp = getLambdaCallOperator();
+ if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate())
+ return Tmpl->getTemplateParameters();
+ return 0;
+}
static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
QualType T;
@@ -1085,16 +1152,21 @@ static void CollectVisibleConversions(ASTContext &Context,
/// in current class; including conversion function templates.
std::pair<CXXRecordDecl::conversion_iterator,CXXRecordDecl::conversion_iterator>
CXXRecordDecl::getVisibleConversionFunctions() {
- // If root class, all conversions are visible.
- if (bases_begin() == bases_end())
- return std::make_pair(data().Conversions.begin(), data().Conversions.end());
- // If visible conversion list is already evaluated, return it.
- if (!data().ComputedVisibleConversions) {
- CollectVisibleConversions(getASTContext(), this, data().VisibleConversions);
- data().ComputedVisibleConversions = true;
+ ASTContext &Ctx = getASTContext();
+
+ ASTUnresolvedSet *Set;
+ if (bases_begin() == bases_end()) {
+ // If root class, all conversions are visible.
+ Set = &data().Conversions.get(Ctx);
+ } else {
+ Set = &data().VisibleConversions.get(Ctx);
+ // If visible conversion list is not evaluated, evaluate it.
+ if (!data().ComputedVisibleConversions) {
+ CollectVisibleConversions(Ctx, this, *Set);
+ data().ComputedVisibleConversions = true;
+ }
}
- return std::make_pair(data().VisibleConversions.begin(),
- data().VisibleConversions.end());
+ return std::make_pair(Set->begin(), Set->end());
}
void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
@@ -1109,7 +1181,7 @@ void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
// with sufficiently large numbers of directly-declared conversions
// that asymptotic behavior matters.
- ASTUnresolvedSet &Convs = data().Conversions;
+ ASTUnresolvedSet &Convs = data().Conversions.get(getASTContext());
for (unsigned I = 0, E = Convs.size(); I != E; ++I) {
if (Convs[I].getDecl() == ConvDecl) {
Convs.erase(I);
@@ -1134,7 +1206,7 @@ CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
TemplateSpecializationKind TSK) {
assert(TemplateOrInstantiation.isNull() &&
"Previous template or instantiation?");
- assert(!isa<ClassTemplateSpecializationDecl>(this));
+ assert(!isa<ClassTemplatePartialSpecializationDecl>(this));
TemplateOrInstantiation
= new (getASTContext()) MemberSpecializationInfo(RD, TSK);
}
@@ -1235,8 +1307,7 @@ void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
}
// Set access bits correctly on the directly-declared conversions.
- for (UnresolvedSetIterator I = data().Conversions.begin(),
- E = data().Conversions.end();
+ for (conversion_iterator I = conversion_begin(), E = conversion_end();
I != E; ++I)
I.setAccess((*I)->getAccess());
}
@@ -1266,21 +1337,8 @@ bool CXXMethodDecl::isStatic() const {
if (MD->getStorageClass() == SC_Static)
return true;
- DeclarationName Name = getDeclName();
- // [class.free]p1:
- // Any allocation function for a class T is a static member
- // (even if not explicitly declared static).
- if (Name.getCXXOverloadedOperator() == OO_New ||
- Name.getCXXOverloadedOperator() == OO_Array_New)
- return true;
-
- // [class.free]p6 Any deallocation function for a class X is a static member
- // (even if not explicitly declared static).
- if (Name.getCXXOverloadedOperator() == OO_Delete ||
- Name.getCXXOverloadedOperator() == OO_Array_Delete)
- return true;
-
- return false;
+ OverloadedOperatorKind OOK = getDeclName().getCXXOverloadedOperator();
+ return isStaticOverloadedOperator(OOK);
}
static bool recursivelyOverrides(const CXXMethodDecl *DerivedMD,
@@ -1408,7 +1466,8 @@ bool CXXMethodDecl::isCopyAssignmentOperator() const {
// type X, X&, const X&, volatile X& or const volatile X&.
if (/*operator=*/getOverloadedOperator() != OO_Equal ||
/*non-static*/ isStatic() ||
- /*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate())
+ /*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate() ||
+ getNumParams() != 1)
return false;
QualType ParamType = getParamDecl(0)->getType();
@@ -1427,7 +1486,8 @@ bool CXXMethodDecl::isMoveAssignmentOperator() const {
// non-template member function of class X with exactly one parameter of type
// X&&, const X&&, volatile X&&, or const volatile X&&.
if (getOverloadedOperator() != OO_Equal || isStatic() ||
- getPrimaryTemplate() || getDescribedFunctionTemplate())
+ getPrimaryTemplate() || getDescribedFunctionTemplate() ||
+ getNumParams() != 1)
return false;
QualType ParamType = getParamDecl(0)->getType();
@@ -1492,11 +1552,17 @@ bool CXXMethodDecl::hasInlineBody() const {
}
bool CXXMethodDecl::isLambdaStaticInvoker() const {
- return getParent()->isLambda() &&
- getIdentifier() && getIdentifier()->getName() == "__invoke";
+ const CXXRecordDecl *P = getParent();
+ if (P->isLambda()) {
+ if (const CXXMethodDecl *StaticInvoker = P->getLambdaStaticInvoker()) {
+ if (StaticInvoker == this) return true;
+ if (P->isGenericLambda() && this->isFunctionTemplateSpecialization())
+ return StaticInvoker == this->getPrimaryTemplate()->getTemplatedDecl();
+ }
+ }
+ return false;
}
-
CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
TypeSourceInfo *TInfo, bool IsVirtual,
SourceLocation L, Expr *Init,
@@ -1865,7 +1931,7 @@ NamespaceDecl::NamespaceDecl(DeclContext *DC, bool Inline,
: NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
LocStart(StartLoc), RBraceLoc(), AnonOrFirstNamespaceAndInline(0, Inline)
{
- setPreviousDeclaration(PrevDecl);
+ setPreviousDecl(PrevDecl);
if (PrevDecl)
AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace());
@@ -1959,8 +2025,8 @@ void UsingDecl::removeShadowDecl(UsingShadowDecl *S) {
UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
- bool IsTypeNameArg) {
- return new (C) UsingDecl(DC, UL, QualifierLoc, NameInfo, IsTypeNameArg);
+ bool HasTypename) {
+ return new (C) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename);
}
UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
@@ -1969,6 +2035,12 @@ UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
DeclarationNameInfo(), false);
}
+SourceRange UsingDecl::getSourceRange() const {
+ SourceLocation Begin = isAccessDeclaration()
+ ? getQualifierLoc().getBeginLoc() : UsingLocation;
+ return SourceRange(Begin, getNameInfo().getEndLoc());
+}
+
void UnresolvedUsingValueDecl::anchor() { }
UnresolvedUsingValueDecl *
@@ -1988,6 +2060,12 @@ UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
DeclarationNameInfo());
}
+SourceRange UnresolvedUsingValueDecl::getSourceRange() const {
+ SourceLocation Begin = isAccessDeclaration()
+ ? getQualifierLoc().getBeginLoc() : UsingLocation;
+ return SourceRange(Begin, getNameInfo().getEndLoc());
+}
+
void UnresolvedUsingTypenameDecl::anchor() { }
UnresolvedUsingTypenameDecl *
OpenPOWER on IntegriCloud