summaryrefslogtreecommitdiff
path: root/include/clang/AST/DeclCXX.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/DeclCXX.h')
-rw-r--r--include/clang/AST/DeclCXX.h206
1 files changed, 178 insertions, 28 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index c19c200f265d..41474ab21e32 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -92,6 +92,53 @@ namespace llvm {
namespace clang {
+/// AccessSpecDecl - An access specifier followed by colon ':'.
+///
+/// An objects of this class represents sugar for the syntactic occurrence
+/// of an access specifier followed by a colon in the list of member
+/// specifiers of a C++ class definition.
+///
+/// Note that they do not represent other uses of access specifiers,
+/// such as those occurring in a list of base specifiers.
+/// Also note that this class has nothing to do with so-called
+/// "access declarations" (C++98 11.3 [class.access.dcl]).
+class AccessSpecDecl : public Decl {
+ /// ColonLoc - The location of the ':'.
+ SourceLocation ColonLoc;
+
+ AccessSpecDecl(AccessSpecifier AS, DeclContext *DC,
+ SourceLocation ASLoc, SourceLocation ColonLoc)
+ : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
+ setAccess(AS);
+ }
+public:
+ /// getAccessSpecifierLoc - The location of the access specifier.
+ SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
+ /// setAccessSpecifierLoc - Sets the location of the access specifier.
+ void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
+
+ /// getColonLoc - The location of the colon following the access specifier.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+ /// setColonLoc - Sets the location of the colon.
+ void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(getAccessSpecifierLoc(), getColonLoc());
+ }
+
+ static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
+ DeclContext *DC, SourceLocation ASLoc,
+ SourceLocation ColonLoc) {
+ return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const AccessSpecDecl *D) { return true; }
+ static bool classofKind(Kind K) { return K == AccessSpec; }
+};
+
+
/// CXXBaseSpecifier - A base class of a C++ class.
///
/// Each CXXBaseSpecifier represents a single, direct base class (or
@@ -271,7 +318,20 @@ class CXXRecordDecl : public RecordDecl {
/// ComputedVisibleConversions - True when visible conversion functions are
/// already computed and are available.
bool ComputedVisibleConversions : 1;
-
+
+ /// \brief Whether we have already declared the default constructor or
+ /// do not need to have one declared.
+ bool DeclaredDefaultConstructor : 1;
+
+ /// \brief Whether we have already declared the copy constructor.
+ bool DeclaredCopyConstructor : 1;
+
+ /// \brief Whether we have already declared the copy-assignment operator.
+ bool DeclaredCopyAssignment : 1;
+
+ /// \brief Whether we have already declared a destructor within the class.
+ bool DeclaredDestructor : 1;
+
/// Bases - Base classes of this class.
/// FIXME: This is wasted space for a union.
CXXBaseSpecifier *Bases;
@@ -367,6 +427,13 @@ public:
virtual const CXXRecordDecl *getCanonicalDecl() const {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
+
+ const CXXRecordDecl *getPreviousDeclaration() const {
+ return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDeclaration());
+ }
+ CXXRecordDecl *getPreviousDeclaration() {
+ return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDeclaration());
+ }
CXXRecordDecl *getDefinition() const {
if (!DefinitionData) return 0;
@@ -380,6 +447,7 @@ public:
SourceLocation TKL = SourceLocation(),
CXXRecordDecl* PrevDecl=0,
bool DelayTypeCreation = false);
+ static CXXRecordDecl *Create(ASTContext &C, EmptyShell Empty);
virtual void Destroy(ASTContext& C);
@@ -476,6 +544,20 @@ public:
return data().FirstFriend != 0;
}
+ /// \brief Determine whether this class has had its default constructor
+ /// declared implicitly or does not need one declared implicitly.
+ ///
+ /// This value is used for lazy creation of default constructors.
+ bool hasDeclaredDefaultConstructor() const {
+ return data().DeclaredDefaultConstructor;
+ }
+
+ /// \brief Note whether this class has already had its default constructor
+ /// implicitly declared or doesn't need one.
+ void setDeclaredDefaultConstructor(bool DDC) {
+ data().DeclaredDefaultConstructor = DDC;
+ }
+
/// hasConstCopyConstructor - Determines whether this class has a
/// copy constructor that accepts a const-qualified argument.
bool hasConstCopyConstructor(ASTContext &Context) const;
@@ -484,12 +566,18 @@ public:
CXXConstructorDecl *getCopyConstructor(ASTContext &Context,
unsigned TypeQuals) const;
- /// hasConstCopyAssignment - Determines whether this class has a
- /// copy assignment operator that accepts a const-qualified argument.
- /// It returns its decl in MD if found.
- bool hasConstCopyAssignment(ASTContext &Context,
- const CXXMethodDecl *&MD) const;
-
+ /// \brief Retrieve the copy-assignment operator for this class, if available.
+ ///
+ /// This routine attempts to find the copy-assignment operator for this
+ /// class, using a simplistic form of overload resolution.
+ ///
+ /// \param ArgIsConst Whether the argument to the copy-assignment operator
+ /// is const-qualified.
+ ///
+ /// \returns The copy-assignment operator that can be invoked, or NULL if
+ /// a unique copy-assignment operator could not be found.
+ CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const;
+
/// addedConstructor - Notify the class that another constructor has
/// been added. This routine helps maintain information about the
/// class based on which constructors have been added.
@@ -509,9 +597,23 @@ public:
return data().UserDeclaredCopyConstructor;
}
+ /// \brief Determine whether this class has had its copy constructor
+ /// declared, either via the user or via an implicit declaration.
+ ///
+ /// This value is used for lazy creation of copy constructors.
+ bool hasDeclaredCopyConstructor() const {
+ return data().DeclaredCopyConstructor;
+ }
+
+ /// \brief Note whether this class has already had its copy constructor
+ /// declared.
+ void setDeclaredCopyConstructor(bool DCC) {
+ data().DeclaredCopyConstructor = DCC;
+ }
+
/// addedAssignmentOperator - Notify the class that another assignment
/// operator has been added. This routine helps maintain information about the
- /// class based on which operators have been added.
+ /// class based on which operators have been added.
void addedAssignmentOperator(ASTContext &Context, CXXMethodDecl *OpDecl);
/// hasUserDeclaredCopyAssignment - Whether this class has a
@@ -521,6 +623,20 @@ public:
return data().UserDeclaredCopyAssignment;
}
+ /// \brief Determine whether this class has had its copy assignment operator
+ /// declared, either via the user or via an implicit declaration.
+ ///
+ /// This value is used for lazy creation of copy assignment operators.
+ bool hasDeclaredCopyAssignment() const {
+ return data().DeclaredCopyAssignment;
+ }
+
+ /// \brief Note whether this class has already had its copy assignment
+ /// operator declared.
+ void setDeclaredCopyAssignment(bool DCA) {
+ data().DeclaredCopyAssignment = DCA;
+ }
+
/// hasUserDeclaredDestructor - Whether this class has a
/// user-declared destructor. When false, a destructor will be
/// implicitly declared.
@@ -533,8 +649,21 @@ public:
/// fully defined, a destructor will be implicitly declared.
void setUserDeclaredDestructor(bool UCD) {
data().UserDeclaredDestructor = UCD;
+ if (UCD)
+ data().DeclaredDestructor = true;
}
+ /// \brief Determine whether this class has had its destructor declared,
+ /// either via the user or via an implicit declaration.
+ ///
+ /// This value is used for lazy creation of destructors.
+ bool hasDeclaredDestructor() const { return data().DeclaredDestructor; }
+
+ /// \brief Note whether this class has already had its destructor declared.
+ void setDeclaredDestructor(bool DD) {
+ data().DeclaredDestructor = DD;
+ }
+
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
UnresolvedSetImpl *getConversionFunctions() {
@@ -726,10 +855,10 @@ public:
void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
/// getDefaultConstructor - Returns the default constructor for this class
- CXXConstructorDecl *getDefaultConstructor(ASTContext &Context);
+ CXXConstructorDecl *getDefaultConstructor();
/// getDestructor - Returns the destructor decl for this class.
- CXXDestructorDecl *getDestructor(ASTContext &Context) const;
+ CXXDestructorDecl *getDestructor() const;
/// isLocalClass - If the class is a local class [class.local], returns
/// the enclosing function declaration.
@@ -920,14 +1049,15 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
- return K == CXXRecord ||
- K == ClassTemplateSpecialization ||
- K == ClassTemplatePartialSpecialization;
+ return K >= firstCXXRecord && K <= lastCXXRecord;
}
static bool classof(const CXXRecordDecl *D) { return true; }
static bool classof(const ClassTemplateSpecializationDecl *D) {
return true;
}
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// CXXMethodDecl - Represents a static or instance method of a
@@ -984,6 +1114,7 @@ public:
method_iterator begin_overridden_methods() const;
method_iterator end_overridden_methods() const;
+ unsigned size_overridden_methods() const;
/// getParent - Returns the parent of this method declaration, which
/// is the class in which this method is defined.
@@ -1012,7 +1143,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXMethodDecl *D) { return true; }
static bool classofKind(Kind K) {
- return K >= CXXMethod && K <= CXXConversion;
+ return K >= firstCXXMethod && K <= lastCXXMethod;
}
};
@@ -1387,6 +1518,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConstructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConstructor; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// CXXDestructorDecl - Represents a C++ destructor within a
@@ -1450,6 +1584,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXDestructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXDestructor; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// CXXConversionDecl - Represents a C++ conversion function within a
@@ -1504,6 +1641,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConversionDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConversion; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// LinkageSpecDecl - This represents a linkage specification. For example:
@@ -1607,7 +1747,7 @@ class UsingDirectiveDecl : public NamedDecl {
SourceLocation IdentLoc,
NamedDecl *Nominated,
DeclContext *CommonAncestor)
- : NamedDecl(Decl::UsingDirective, DC, L, getName()),
+ : NamedDecl(UsingDirective, DC, L, getName()),
NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange),
Qualifier(Qualifier), IdentLoc(IdentLoc),
NominatedNamespace(Nominated),
@@ -1680,7 +1820,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingDirectiveDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::UsingDirective; }
+ static bool classofKind(Kind K) { return K == UsingDirective; }
// Friend for getUsingDirectiveName.
friend class DeclContext;
@@ -1714,7 +1854,7 @@ class NamespaceAliasDecl : public NamedDecl {
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc, NamedDecl *Namespace)
- : NamedDecl(Decl::NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc),
+ : NamedDecl(NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc),
QualifierRange(QualifierRange), Qualifier(Qualifier),
IdentLoc(IdentLoc), Namespace(Namespace) { }
@@ -1786,7 +1926,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamespaceAliasDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::NamespaceAlias; }
+ static bool classofKind(Kind K) { return K == NamespaceAlias; }
};
/// UsingShadowDecl - Represents a shadow declaration introduced into
@@ -1809,9 +1949,12 @@ class UsingShadowDecl : public NamedDecl {
UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
NamedDecl *Target)
- : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()),
+ : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
Underlying(Target), Using(Using) {
- IdentifierNamespace = Target->getIdentifierNamespace();
+ if (Target) {
+ setDeclName(Target->getDeclName());
+ IdentifierNamespace = Target->getIdentifierNamespace();
+ }
setImplicit();
}
@@ -1828,7 +1971,11 @@ public:
/// \brief Sets the underlying declaration which has been brought into the
/// local scope.
- void setTargetDecl(NamedDecl* ND) { Underlying = ND; }
+ void setTargetDecl(NamedDecl* ND) {
+ assert(ND && "Target decl is null!");
+ Underlying = ND;
+ IdentifierNamespace = ND->getIdentifierNamespace();
+ }
/// \brief Gets the using declaration to which this declaration is tied.
UsingDecl *getUsingDecl() const { return Using; }
@@ -1866,7 +2013,7 @@ class UsingDecl : public NamedDecl {
UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
SourceLocation UL, NestedNameSpecifier* TargetNNS,
DeclarationName Name, bool IsTypeNameArg)
- : NamedDecl(Decl::Using, DC, L, Name),
+ : NamedDecl(Using, DC, L, Name),
NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
IsTypeName(IsTypeNameArg) {
}
@@ -1934,7 +2081,10 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::Using; }
+ static bool classofKind(Kind K) { return K == Using; }
+
+ friend class PCHDeclReader;
+ friend class PCHDeclWriter;
};
/// UnresolvedUsingValueDecl - Represents a dependent using
@@ -1960,7 +2110,7 @@ class UnresolvedUsingValueDecl : public ValueDecl {
NestedNameSpecifier *TargetNNS,
SourceLocation TargetNameLoc,
DeclarationName TargetName)
- : ValueDecl(Decl::UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
+ : ValueDecl(UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
TargetNestedNameSpecifier(TargetNNS)
{ }
@@ -1997,7 +2147,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingValue; }
+ static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
};
/// UnresolvedUsingTypenameDecl - Represents a dependent using
@@ -2026,7 +2176,7 @@ class UnresolvedUsingTypenameDecl : public TypeDecl {
SourceLocation TypenameLoc,
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
- : TypeDecl(Decl::UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
+ : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
{ }
@@ -2070,7 +2220,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingTypename; }
+ static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
};
/// StaticAssertDecl - Represents a C++0x static_assert declaration.
@@ -2098,7 +2248,7 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(StaticAssertDecl *D) { return true; }
- static bool classofKind(Kind K) { return K == Decl::StaticAssert; }
+ static bool classofKind(Kind K) { return K == StaticAssert; }
};
/// Insertion operator for diagnostics. This allows sending AccessSpecifier's