2009-06-02 17:58:47 +00:00
|
|
|
//===-- DeclBase.h - Base Classes for representing declarations -*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file defines the Decl and DeclContext interfaces.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_CLANG_AST_DECLBASE_H
|
|
|
|
#define LLVM_CLANG_AST_DECLBASE_H
|
|
|
|
|
|
|
|
#include "clang/AST/Attr.h"
|
|
|
|
#include "clang/AST/Type.h"
|
2010-01-23 11:10:26 +00:00
|
|
|
#include "clang/Basic/Specifiers.h"
|
2009-06-02 17:58:47 +00:00
|
|
|
#include "llvm/Support/PrettyStackTrace.h"
|
|
|
|
#include "llvm/ADT/PointerUnion.h"
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
class DeclContext;
|
|
|
|
class TranslationUnitDecl;
|
|
|
|
class NamespaceDecl;
|
|
|
|
class UsingDirectiveDecl;
|
|
|
|
class NamedDecl;
|
|
|
|
class FunctionDecl;
|
|
|
|
class CXXRecordDecl;
|
|
|
|
class EnumDecl;
|
|
|
|
class ObjCMethodDecl;
|
|
|
|
class ObjCContainerDecl;
|
|
|
|
class ObjCInterfaceDecl;
|
|
|
|
class ObjCCategoryDecl;
|
|
|
|
class ObjCProtocolDecl;
|
|
|
|
class ObjCImplementationDecl;
|
|
|
|
class ObjCCategoryImplDecl;
|
2009-10-14 18:03:49 +00:00
|
|
|
class ObjCImplDecl;
|
2009-06-02 17:58:47 +00:00
|
|
|
class LinkageSpecDecl;
|
|
|
|
class BlockDecl;
|
|
|
|
class DeclarationName;
|
|
|
|
class CompoundStmt;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
// DeclContext* is only 4-byte aligned on 32-bit systems.
|
|
|
|
template<>
|
|
|
|
class PointerLikeTypeTraits<clang::DeclContext*> {
|
|
|
|
typedef clang::DeclContext* PT;
|
|
|
|
public:
|
|
|
|
static inline void *getAsVoidPointer(PT P) { return P; }
|
|
|
|
static inline PT getFromVoidPointer(void *P) {
|
|
|
|
return static_cast<PT>(P);
|
|
|
|
}
|
|
|
|
enum { NumLowBitsAvailable = 2 };
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
/// Decl - This represents one declaration (or definition), e.g. a variable,
|
|
|
|
/// typedef, function, struct, etc.
|
2009-06-02 17:58:47 +00:00
|
|
|
///
|
|
|
|
class Decl {
|
|
|
|
public:
|
|
|
|
/// \brief Lists the kind of concrete classes of Decl.
|
|
|
|
enum Kind {
|
|
|
|
#define DECL(Derived, Base) Derived,
|
|
|
|
#define DECL_RANGE(CommonBase, Start, End) \
|
2009-10-14 18:03:49 +00:00
|
|
|
CommonBase##First = Start, CommonBase##Last = End,
|
2009-06-02 17:58:47 +00:00
|
|
|
#define LAST_DECL_RANGE(CommonBase, Start, End) \
|
|
|
|
CommonBase##First = Start, CommonBase##Last = End
|
|
|
|
#include "clang/AST/DeclNodes.def"
|
|
|
|
};
|
|
|
|
|
|
|
|
/// IdentifierNamespace - According to C99 6.2.3, there are four
|
|
|
|
/// namespaces, labels, tags, members and ordinary
|
|
|
|
/// identifiers. These are meant as bitmasks, so that searches in
|
|
|
|
/// C++ can look into the "tag" namespace during ordinary lookup. We
|
2009-11-18 14:59:57 +00:00
|
|
|
/// use additional namespaces for Objective-C entities. We also put
|
|
|
|
/// C++ friend declarations (of previously-undeclared entities) in
|
|
|
|
/// shadow namespaces, and 'using' declarations (as opposed to their
|
|
|
|
/// implicit shadow declarations) can be found in their own
|
|
|
|
/// namespace.
|
2009-06-02 17:58:47 +00:00
|
|
|
enum IdentifierNamespace {
|
|
|
|
IDNS_Label = 0x1,
|
|
|
|
IDNS_Tag = 0x2,
|
|
|
|
IDNS_Member = 0x4,
|
|
|
|
IDNS_Ordinary = 0x8,
|
|
|
|
IDNS_ObjCProtocol = 0x10,
|
|
|
|
IDNS_ObjCImplementation = 0x20,
|
2009-12-15 18:49:47 +00:00
|
|
|
IDNS_ObjCCategoryName = 0x40,
|
2009-10-14 18:03:49 +00:00
|
|
|
IDNS_OrdinaryFriend = 0x80,
|
2009-11-18 14:59:57 +00:00
|
|
|
IDNS_TagFriend = 0x100,
|
|
|
|
IDNS_Using = 0x200
|
2009-06-02 17:58:47 +00:00
|
|
|
};
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// ObjCDeclQualifier - Qualifier used on types in method declarations
|
|
|
|
/// for remote messaging. They are meant for the arguments though and
|
|
|
|
/// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
|
|
|
|
enum ObjCDeclQualifier {
|
|
|
|
OBJC_TQ_None = 0x0,
|
|
|
|
OBJC_TQ_In = 0x1,
|
|
|
|
OBJC_TQ_Inout = 0x2,
|
|
|
|
OBJC_TQ_Out = 0x4,
|
|
|
|
OBJC_TQ_Bycopy = 0x8,
|
|
|
|
OBJC_TQ_Byref = 0x10,
|
|
|
|
OBJC_TQ_Oneway = 0x20
|
|
|
|
};
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
private:
|
|
|
|
/// NextDeclInContext - The next declaration within the same lexical
|
|
|
|
/// DeclContext. These pointers form the linked list that is
|
|
|
|
/// traversed via DeclContext's decls_begin()/decls_end().
|
|
|
|
Decl *NextDeclInContext;
|
|
|
|
|
|
|
|
friend class DeclContext;
|
|
|
|
|
|
|
|
struct MultipleDC {
|
|
|
|
DeclContext *SemanticDC;
|
|
|
|
DeclContext *LexicalDC;
|
|
|
|
};
|
2009-10-14 18:03:49 +00:00
|
|
|
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
|
|
|
|
/// For declarations that don't contain C++ scope specifiers, it contains
|
|
|
|
/// the DeclContext where the Decl was declared.
|
|
|
|
/// For declarations with C++ scope specifiers, it contains a MultipleDC*
|
|
|
|
/// with the context where it semantically belongs (SemanticDC) and the
|
|
|
|
/// context where it was lexically declared (LexicalDC).
|
|
|
|
/// e.g.:
|
|
|
|
///
|
|
|
|
/// namespace A {
|
|
|
|
/// void f(); // SemanticDC == LexicalDC == 'namespace A'
|
|
|
|
/// }
|
|
|
|
/// void A::f(); // SemanticDC == namespace 'A'
|
|
|
|
/// // LexicalDC == global namespace
|
|
|
|
llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
|
|
|
|
|
|
|
|
inline bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
|
|
|
|
inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
|
|
|
|
inline MultipleDC *getMultipleDC() const {
|
|
|
|
return DeclCtx.get<MultipleDC*>();
|
|
|
|
}
|
|
|
|
inline DeclContext *getSemanticDC() const {
|
|
|
|
return DeclCtx.get<DeclContext*>();
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// Loc - The location that this decl.
|
|
|
|
SourceLocation Loc;
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// DeclKind - This indicates which class this is.
|
|
|
|
Kind DeclKind : 8;
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// InvalidDecl - This indicates a semantic error occurred.
|
|
|
|
unsigned int InvalidDecl : 1;
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// HasAttrs - This indicates whether the decl has attributes or not.
|
|
|
|
unsigned int HasAttrs : 1;
|
|
|
|
|
|
|
|
/// Implicit - Whether this declaration was implicitly generated by
|
|
|
|
/// the implementation rather than explicitly written by the user.
|
|
|
|
bool Implicit : 1;
|
|
|
|
|
2009-06-22 08:08:35 +00:00
|
|
|
/// \brief Whether this declaration was "used", meaning that a definition is
|
|
|
|
/// required.
|
|
|
|
bool Used : 1;
|
|
|
|
|
|
|
|
protected:
|
2009-10-23 14:22:18 +00:00
|
|
|
/// Access - Used by C++ decls for the access specifier.
|
|
|
|
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
|
|
|
|
unsigned Access : 2;
|
|
|
|
friend class CXXClassMemberWrapper;
|
|
|
|
|
|
|
|
// PCHLevel - the "level" of precompiled header/AST file from which this
|
|
|
|
// declaration was built.
|
|
|
|
unsigned PCHLevel : 2;
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
|
2009-10-14 18:03:49 +00:00
|
|
|
unsigned IdentifierNamespace : 16;
|
|
|
|
|
2009-06-22 08:08:35 +00:00
|
|
|
private:
|
2009-06-02 17:58:47 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
void CheckAccessDeclContext() const;
|
|
|
|
#else
|
|
|
|
void CheckAccessDeclContext() const { }
|
|
|
|
#endif
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
protected:
|
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
Decl(Kind DK, DeclContext *DC, SourceLocation L)
|
|
|
|
: NextDeclInContext(0), DeclCtx(DC),
|
2009-06-02 17:58:47 +00:00
|
|
|
Loc(L), DeclKind(DK), InvalidDecl(0),
|
2009-06-22 08:08:35 +00:00
|
|
|
HasAttrs(false), Implicit(false), Used(false),
|
2009-10-23 14:22:18 +00:00
|
|
|
Access(AS_none), PCHLevel(0),
|
|
|
|
IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
|
2009-06-02 17:58:47 +00:00
|
|
|
if (Decl::CollectingStats()) addDeclKind(DK);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~Decl();
|
|
|
|
|
|
|
|
public:
|
2009-06-22 08:08:35 +00:00
|
|
|
|
|
|
|
/// \brief Source range that this declaration covers.
|
|
|
|
virtual SourceRange getSourceRange() const {
|
|
|
|
return SourceRange(getLocation(), getLocation());
|
|
|
|
}
|
|
|
|
SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
|
|
|
|
SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
SourceLocation getLocation() const { return Loc; }
|
|
|
|
void setLocation(SourceLocation L) { Loc = L; }
|
|
|
|
|
|
|
|
Kind getKind() const { return DeclKind; }
|
|
|
|
const char *getDeclKindName() const;
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
Decl *getNextDeclInContext() { return NextDeclInContext; }
|
|
|
|
const Decl *getNextDeclInContext() const { return NextDeclInContext; }
|
|
|
|
|
|
|
|
DeclContext *getDeclContext() {
|
|
|
|
if (isInSemaDC())
|
|
|
|
return getSemanticDC();
|
|
|
|
return getMultipleDC()->SemanticDC;
|
|
|
|
}
|
|
|
|
const DeclContext *getDeclContext() const {
|
|
|
|
return const_cast<Decl*>(this)->getDeclContext();
|
|
|
|
}
|
2009-07-04 13:58:54 +00:00
|
|
|
|
|
|
|
TranslationUnitDecl *getTranslationUnitDecl();
|
|
|
|
const TranslationUnitDecl *getTranslationUnitDecl() const {
|
|
|
|
return const_cast<Decl*>(this)->getTranslationUnitDecl();
|
|
|
|
}
|
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
bool isInAnonymousNamespace() const;
|
|
|
|
|
2009-07-04 13:58:54 +00:00
|
|
|
ASTContext &getASTContext() const;
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
void setAccess(AccessSpecifier AS) {
|
2009-10-14 18:03:49 +00:00
|
|
|
Access = AS;
|
2009-06-02 17:58:47 +00:00
|
|
|
CheckAccessDeclContext();
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
|
|
|
AccessSpecifier getAccess() const {
|
2009-06-02 17:58:47 +00:00
|
|
|
CheckAccessDeclContext();
|
2009-10-14 18:03:49 +00:00
|
|
|
return AccessSpecifier(Access);
|
2009-06-02 17:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool hasAttrs() const { return HasAttrs; }
|
2009-07-04 13:58:54 +00:00
|
|
|
void addAttr(Attr *attr);
|
|
|
|
const Attr *getAttrs() const {
|
2009-06-02 17:58:47 +00:00
|
|
|
if (!HasAttrs) return 0; // common case, no attributes.
|
2009-07-04 13:58:54 +00:00
|
|
|
return getAttrsImpl(); // Uncommon case, out of line hash lookup.
|
2009-06-02 17:58:47 +00:00
|
|
|
}
|
2009-07-04 13:58:54 +00:00
|
|
|
void swapAttrs(Decl *D);
|
|
|
|
void invalidateAttrs();
|
2009-06-02 17:58:47 +00:00
|
|
|
|
2009-07-04 13:58:54 +00:00
|
|
|
template<typename T> const T *getAttr() const {
|
|
|
|
for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
|
2009-06-02 17:58:47 +00:00
|
|
|
if (const T *V = dyn_cast<T>(attr))
|
|
|
|
return V;
|
|
|
|
return 0;
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-07-04 13:58:54 +00:00
|
|
|
template<typename T> bool hasAttr() const {
|
|
|
|
return getAttr<T>() != 0;
|
2009-06-02 17:58:47 +00:00
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// setInvalidDecl - Indicates the Decl had a semantic error. This
|
|
|
|
/// allows for graceful error recovery.
|
|
|
|
void setInvalidDecl(bool Invalid = true) { InvalidDecl = Invalid; }
|
|
|
|
bool isInvalidDecl() const { return (bool) InvalidDecl; }
|
|
|
|
|
|
|
|
/// isImplicit - Indicates whether the declaration was implicitly
|
|
|
|
/// generated by the implementation. If false, this declaration
|
|
|
|
/// was written explicitly in the source code.
|
|
|
|
bool isImplicit() const { return Implicit; }
|
|
|
|
void setImplicit(bool I = true) { Implicit = I; }
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-22 08:08:35 +00:00
|
|
|
/// \brief Whether this declaration was used, meaning that a definition
|
|
|
|
/// is required.
|
2010-03-03 17:28:16 +00:00
|
|
|
bool isUsed() const;
|
|
|
|
|
2009-06-22 08:08:35 +00:00
|
|
|
void setUsed(bool U = true) { Used = U; }
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-10-23 14:22:18 +00:00
|
|
|
/// \brief Retrieve the level of precompiled header from which this
|
|
|
|
/// declaration was generated.
|
|
|
|
///
|
|
|
|
/// The PCH level of a declaration describes where the declaration originated
|
|
|
|
/// from. A PCH level of 0 indicates that the declaration was not from a
|
|
|
|
/// precompiled header. A PCH level of 1 indicates that the declaration was
|
|
|
|
/// from a top-level precompiled header; 2 indicates that the declaration
|
|
|
|
/// comes from a precompiled header on which the top-level precompiled header
|
|
|
|
/// depends, and so on.
|
|
|
|
unsigned getPCHLevel() const { return PCHLevel; }
|
|
|
|
|
|
|
|
/// \brief The maximum PCH level that any declaration may have.
|
|
|
|
static const unsigned MaxPCHLevel = 3;
|
|
|
|
|
|
|
|
/// \brief Set the PCH level of this declaration.
|
|
|
|
void setPCHLevel(unsigned Level) {
|
|
|
|
assert(Level < MaxPCHLevel && "PCH level exceeds the maximum");
|
|
|
|
PCHLevel = Level;
|
|
|
|
}
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
unsigned getIdentifierNamespace() const {
|
|
|
|
return IdentifierNamespace;
|
|
|
|
}
|
|
|
|
bool isInIdentifierNamespace(unsigned NS) const {
|
|
|
|
return getIdentifierNamespace() & NS;
|
|
|
|
}
|
|
|
|
static unsigned getIdentifierNamespaceForKind(Kind DK);
|
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// getLexicalDeclContext - The declaration context where this Decl was
|
|
|
|
/// lexically declared (LexicalDC). May be different from
|
|
|
|
/// getDeclContext() (SemanticDC).
|
|
|
|
/// e.g.:
|
|
|
|
///
|
|
|
|
/// namespace A {
|
|
|
|
/// void f(); // SemanticDC == LexicalDC == 'namespace A'
|
|
|
|
/// }
|
|
|
|
/// void A::f(); // SemanticDC == namespace 'A'
|
|
|
|
/// // LexicalDC == global namespace
|
|
|
|
DeclContext *getLexicalDeclContext() {
|
|
|
|
if (isInSemaDC())
|
|
|
|
return getSemanticDC();
|
|
|
|
return getMultipleDC()->LexicalDC;
|
|
|
|
}
|
|
|
|
const DeclContext *getLexicalDeclContext() const {
|
|
|
|
return const_cast<Decl*>(this)->getLexicalDeclContext();
|
|
|
|
}
|
2009-06-22 08:08:35 +00:00
|
|
|
|
2010-03-03 17:28:16 +00:00
|
|
|
virtual bool isOutOfLine() const {
|
2009-06-22 08:08:35 +00:00
|
|
|
return getLexicalDeclContext() != getDeclContext();
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// setDeclContext - Set both the semantic and lexical DeclContext
|
|
|
|
/// to DC.
|
|
|
|
void setDeclContext(DeclContext *DC);
|
|
|
|
|
|
|
|
void setLexicalDeclContext(DeclContext *DC);
|
|
|
|
|
|
|
|
// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
|
|
|
|
// scoped decl is defined outside the current function or method. This is
|
|
|
|
// roughly global variables and functions, but also handles enums (which could
|
|
|
|
// be defined inside or outside a function etc).
|
|
|
|
bool isDefinedOutsideFunctionOrMethod() const;
|
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
/// \brief Retrieves the "canonical" declaration of the given declaration.
|
|
|
|
virtual Decl *getCanonicalDecl() { return this; }
|
|
|
|
const Decl *getCanonicalDecl() const {
|
|
|
|
return const_cast<Decl*>(this)->getCanonicalDecl();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Whether this particular Decl is a canonical one.
|
|
|
|
bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/// \brief Returns the next redeclaration or itself if this is the only decl.
|
|
|
|
///
|
|
|
|
/// Decl subclasses that can be redeclared should override this method so that
|
|
|
|
/// Decl::redecl_iterator can iterate over them.
|
|
|
|
virtual Decl *getNextRedeclaration() { return this; }
|
|
|
|
|
|
|
|
public:
|
|
|
|
/// \brief Iterates through all the redeclarations of the same decl.
|
|
|
|
class redecl_iterator {
|
|
|
|
/// Current - The current declaration.
|
|
|
|
Decl *Current;
|
|
|
|
Decl *Starter;
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef Decl* value_type;
|
|
|
|
typedef Decl* reference;
|
|
|
|
typedef Decl* pointer;
|
|
|
|
typedef std::forward_iterator_tag iterator_category;
|
|
|
|
typedef std::ptrdiff_t difference_type;
|
|
|
|
|
|
|
|
redecl_iterator() : Current(0) { }
|
|
|
|
explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
|
|
|
|
|
|
|
|
reference operator*() const { return Current; }
|
|
|
|
pointer operator->() const { return Current; }
|
|
|
|
|
|
|
|
redecl_iterator& operator++() {
|
|
|
|
assert(Current && "Advancing while iterator has reached end");
|
|
|
|
// Get either previous decl or latest decl.
|
|
|
|
Decl *Next = Current->getNextRedeclaration();
|
|
|
|
assert(Next && "Should return next redeclaration or itself, never null!");
|
|
|
|
Current = (Next != Starter ? Next : 0);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
redecl_iterator operator++(int) {
|
|
|
|
redecl_iterator tmp(*this);
|
|
|
|
++(*this);
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
friend bool operator==(redecl_iterator x, redecl_iterator y) {
|
|
|
|
return x.Current == y.Current;
|
|
|
|
}
|
|
|
|
friend bool operator!=(redecl_iterator x, redecl_iterator y) {
|
|
|
|
return x.Current != y.Current;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Returns iterator for all the redeclarations of the same decl.
|
|
|
|
/// It will iterate at least once (when this decl is the only one).
|
|
|
|
redecl_iterator redecls_begin() const {
|
|
|
|
return redecl_iterator(const_cast<Decl*>(this));
|
|
|
|
}
|
|
|
|
redecl_iterator redecls_end() const { return redecl_iterator(); }
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// getBody - If this Decl represents a declaration for a body of code,
|
|
|
|
/// such as a function or method definition, this method returns the
|
|
|
|
/// top-level Stmt* of that body. Otherwise this method returns null.
|
2009-07-04 13:58:54 +00:00
|
|
|
virtual Stmt* getBody() const { return 0; }
|
2009-06-02 17:58:47 +00:00
|
|
|
|
|
|
|
/// getCompoundBody - Returns getBody(), dyn_casted to a CompoundStmt.
|
2009-07-04 13:58:54 +00:00
|
|
|
CompoundStmt* getCompoundBody() const;
|
2009-06-02 17:58:47 +00:00
|
|
|
|
|
|
|
/// getBodyRBrace - Gets the right brace of the body, if a body exists.
|
|
|
|
/// This works whether the body is a CompoundStmt or a CXXTryStmt.
|
2009-07-04 13:58:54 +00:00
|
|
|
SourceLocation getBodyRBrace() const;
|
2009-06-02 17:58:47 +00:00
|
|
|
|
|
|
|
// global temp stats (until we have a per-module visitor)
|
|
|
|
static void addDeclKind(Kind k);
|
|
|
|
static bool CollectingStats(bool Enable = false);
|
|
|
|
static void PrintStats();
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-14 09:24:02 +00:00
|
|
|
/// isTemplateParameter - Determines whether this declaration is a
|
2009-06-02 17:58:47 +00:00
|
|
|
/// template parameter.
|
|
|
|
bool isTemplateParameter() const;
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-14 09:24:02 +00:00
|
|
|
/// isTemplateParameter - Determines whether this declaration is a
|
|
|
|
/// template parameter pack.
|
|
|
|
bool isTemplateParameterPack() const;
|
2009-06-02 17:58:47 +00:00
|
|
|
|
2009-06-27 10:45:02 +00:00
|
|
|
/// \brief Whether this declaration is a function or function template.
|
|
|
|
bool isFunctionOrFunctionTemplate() const;
|
2009-10-14 18:03:49 +00:00
|
|
|
|
|
|
|
/// \brief Changes the namespace of this declaration to reflect that it's
|
|
|
|
/// the object of a friend declaration.
|
|
|
|
///
|
|
|
|
/// These declarations appear in the lexical context of the friending
|
|
|
|
/// class, but in the semantic context of the actual entity. This property
|
|
|
|
/// applies only to a specific decl object; other redeclarations of the
|
|
|
|
/// same entity may not (and probably don't) share this property.
|
|
|
|
void setObjectOfFriendDecl(bool PreviouslyDeclared) {
|
|
|
|
unsigned OldNS = IdentifierNamespace;
|
|
|
|
assert((OldNS == IDNS_Tag || OldNS == IDNS_Ordinary ||
|
|
|
|
OldNS == (IDNS_Tag | IDNS_Ordinary))
|
|
|
|
&& "unsupported namespace for undeclared friend");
|
|
|
|
if (!PreviouslyDeclared) IdentifierNamespace = 0;
|
|
|
|
|
|
|
|
if (OldNS == IDNS_Tag)
|
|
|
|
IdentifierNamespace |= IDNS_TagFriend;
|
|
|
|
else
|
|
|
|
IdentifierNamespace |= IDNS_OrdinaryFriend;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum FriendObjectKind {
|
|
|
|
FOK_None, // not a friend object
|
|
|
|
FOK_Declared, // a friend of a previously-declared entity
|
|
|
|
FOK_Undeclared // a friend of a previously-undeclared entity
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Determines whether this declaration is the object of a
|
|
|
|
/// friend declaration and, if so, what kind.
|
|
|
|
///
|
|
|
|
/// There is currently no direct way to find the associated FriendDecl.
|
|
|
|
FriendObjectKind getFriendObjectKind() const {
|
|
|
|
unsigned mask
|
|
|
|
= (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend));
|
|
|
|
if (!mask) return FOK_None;
|
|
|
|
return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ?
|
|
|
|
FOK_Declared : FOK_Undeclared);
|
|
|
|
}
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
|
|
static bool classof(const Decl *) { return true; }
|
2010-02-16 09:31:36 +00:00
|
|
|
static bool classofKind(Kind K) { return true; }
|
2009-06-02 17:58:47 +00:00
|
|
|
static DeclContext *castToDeclContext(const Decl *);
|
|
|
|
static Decl *castFromDeclContext(const DeclContext *);
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// Destroy - Call destructors and release memory.
|
|
|
|
virtual void Destroy(ASTContext& C);
|
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
void print(llvm::raw_ostream &Out, unsigned Indentation = 0) const;
|
2009-07-04 13:58:54 +00:00
|
|
|
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
|
2009-10-14 18:03:49 +00:00
|
|
|
unsigned Indentation = 0) const;
|
2009-06-02 17:58:47 +00:00
|
|
|
static void printGroup(Decl** Begin, unsigned NumDecls,
|
2009-07-04 13:58:54 +00:00
|
|
|
llvm::raw_ostream &Out, const PrintingPolicy &Policy,
|
2009-06-02 17:58:47 +00:00
|
|
|
unsigned Indentation = 0);
|
2009-10-14 18:03:49 +00:00
|
|
|
void dump() const;
|
2009-06-02 17:58:47 +00:00
|
|
|
|
|
|
|
private:
|
2009-07-04 13:58:54 +00:00
|
|
|
const Attr *getAttrsImpl() const;
|
2009-06-02 17:58:47 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
|
|
|
|
/// doing something to a specific decl.
|
|
|
|
class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
|
2009-12-01 11:08:04 +00:00
|
|
|
const Decl *TheDecl;
|
2009-06-02 17:58:47 +00:00
|
|
|
SourceLocation Loc;
|
|
|
|
SourceManager &SM;
|
|
|
|
const char *Message;
|
|
|
|
public:
|
2009-12-01 11:08:04 +00:00
|
|
|
PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
|
2009-06-02 17:58:47 +00:00
|
|
|
SourceManager &sm, const char *Msg)
|
|
|
|
: TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
virtual void print(llvm::raw_ostream &OS) const;
|
2009-10-14 18:03:49 +00:00
|
|
|
};
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
|
|
|
|
/// DeclContext - This is used only as base class of specific decl types that
|
|
|
|
/// can act as declaration contexts. These decls are (only the top classes
|
|
|
|
/// that directly derive from DeclContext are mentioned, not their subclasses):
|
|
|
|
///
|
|
|
|
/// TranslationUnitDecl
|
|
|
|
/// NamespaceDecl
|
|
|
|
/// FunctionDecl
|
|
|
|
/// TagDecl
|
|
|
|
/// ObjCMethodDecl
|
|
|
|
/// ObjCContainerDecl
|
|
|
|
/// LinkageSpecDecl
|
|
|
|
/// BlockDecl
|
|
|
|
///
|
|
|
|
class DeclContext {
|
|
|
|
/// DeclKind - This indicates which class this is.
|
|
|
|
Decl::Kind DeclKind : 8;
|
|
|
|
|
|
|
|
/// \brief Whether this declaration context also has some external
|
|
|
|
/// storage that contains additional declarations that are lexically
|
|
|
|
/// part of this context.
|
|
|
|
mutable bool ExternalLexicalStorage : 1;
|
|
|
|
|
|
|
|
/// \brief Whether this declaration context also has some external
|
|
|
|
/// storage that contains additional declarations that are visible
|
|
|
|
/// in this context.
|
|
|
|
mutable bool ExternalVisibleStorage : 1;
|
|
|
|
|
|
|
|
/// \brief Pointer to the data structure used to lookup declarations
|
|
|
|
/// within this context, which is a DenseMap<DeclarationName,
|
|
|
|
/// StoredDeclsList>.
|
|
|
|
mutable void* LookupPtr;
|
|
|
|
|
|
|
|
/// FirstDecl - The first declaration stored within this declaration
|
|
|
|
/// context.
|
|
|
|
mutable Decl *FirstDecl;
|
|
|
|
|
|
|
|
/// LastDecl - The last declaration stored within this declaration
|
|
|
|
/// context. FIXME: We could probably cache this value somewhere
|
|
|
|
/// outside of the DeclContext, to reduce the size of DeclContext by
|
|
|
|
/// another pointer.
|
|
|
|
mutable Decl *LastDecl;
|
|
|
|
|
|
|
|
protected:
|
2009-10-14 18:03:49 +00:00
|
|
|
DeclContext(Decl::Kind K)
|
2009-06-02 17:58:47 +00:00
|
|
|
: DeclKind(K), ExternalLexicalStorage(false),
|
2009-10-14 18:03:49 +00:00
|
|
|
ExternalVisibleStorage(false), LookupPtr(0), FirstDecl(0),
|
2009-06-02 17:58:47 +00:00
|
|
|
LastDecl(0) { }
|
|
|
|
|
|
|
|
void DestroyDecls(ASTContext &C);
|
|
|
|
|
|
|
|
public:
|
|
|
|
~DeclContext();
|
|
|
|
|
|
|
|
Decl::Kind getDeclKind() const {
|
|
|
|
return DeclKind;
|
|
|
|
}
|
|
|
|
const char *getDeclKindName() const;
|
|
|
|
|
|
|
|
/// getParent - Returns the containing DeclContext.
|
|
|
|
DeclContext *getParent() {
|
|
|
|
return cast<Decl>(this)->getDeclContext();
|
|
|
|
}
|
|
|
|
const DeclContext *getParent() const {
|
|
|
|
return const_cast<DeclContext*>(this)->getParent();
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// getLexicalParent - Returns the containing lexical DeclContext. May be
|
|
|
|
/// different from getParent, e.g.:
|
|
|
|
///
|
|
|
|
/// namespace A {
|
|
|
|
/// struct S;
|
|
|
|
/// }
|
|
|
|
/// struct A::S {}; // getParent() == namespace 'A'
|
|
|
|
/// // getLexicalParent() == translation unit
|
|
|
|
///
|
|
|
|
DeclContext *getLexicalParent() {
|
|
|
|
return cast<Decl>(this)->getLexicalDeclContext();
|
|
|
|
}
|
|
|
|
const DeclContext *getLexicalParent() const {
|
|
|
|
return const_cast<DeclContext*>(this)->getLexicalParent();
|
2009-10-14 18:03:49 +00:00
|
|
|
}
|
2009-07-04 13:58:54 +00:00
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
DeclContext *getLookupParent();
|
|
|
|
|
|
|
|
const DeclContext *getLookupParent() const {
|
|
|
|
return const_cast<DeclContext*>(this)->getLookupParent();
|
|
|
|
}
|
|
|
|
|
2009-07-04 13:58:54 +00:00
|
|
|
ASTContext &getParentASTContext() const {
|
|
|
|
return cast<Decl>(this)->getASTContext();
|
|
|
|
}
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
bool isFunctionOrMethod() const {
|
|
|
|
switch (DeclKind) {
|
|
|
|
case Decl::Block:
|
|
|
|
case Decl::ObjCMethod:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isFileContext() const {
|
|
|
|
return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isTranslationUnit() const {
|
|
|
|
return DeclKind == Decl::TranslationUnit;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isRecord() const {
|
|
|
|
return DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isNamespace() const {
|
|
|
|
return DeclKind == Decl::Namespace;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Determines whether this context is dependent on a
|
|
|
|
/// template parameter.
|
|
|
|
bool isDependentContext() const;
|
|
|
|
|
|
|
|
/// isTransparentContext - Determines whether this context is a
|
|
|
|
/// "transparent" context, meaning that the members declared in this
|
|
|
|
/// context are semantically declared in the nearest enclosing
|
|
|
|
/// non-transparent (opaque) context but are lexically declared in
|
|
|
|
/// this context. For example, consider the enumerators of an
|
2009-10-14 18:03:49 +00:00
|
|
|
/// enumeration type:
|
2009-06-02 17:58:47 +00:00
|
|
|
/// @code
|
|
|
|
/// enum E {
|
2009-10-14 18:03:49 +00:00
|
|
|
/// Val1
|
2009-06-02 17:58:47 +00:00
|
|
|
/// };
|
|
|
|
/// @endcode
|
|
|
|
/// Here, E is a transparent context, so its enumerator (Val1) will
|
|
|
|
/// appear (semantically) that it is in the same context of E.
|
|
|
|
/// Examples of transparent contexts include: enumerations (except for
|
|
|
|
/// C++0x scoped enums), C++ linkage specifications, and C++0x
|
|
|
|
/// inline namespaces.
|
|
|
|
bool isTransparentContext() const;
|
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
/// \brief Determine whether this declaration context is equivalent
|
|
|
|
/// to the declaration context DC.
|
|
|
|
bool Equals(DeclContext *DC) {
|
|
|
|
return this->getPrimaryContext() == DC->getPrimaryContext();
|
2009-06-02 17:58:47 +00:00
|
|
|
}
|
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
/// \brief Determine whether this declaration context encloses the
|
|
|
|
/// declaration context DC.
|
|
|
|
bool Encloses(DeclContext *DC);
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// getPrimaryContext - There may be many different
|
|
|
|
/// declarations of the same entity (including forward declarations
|
|
|
|
/// of classes, multiple definitions of namespaces, etc.), each with
|
|
|
|
/// a different set of declarations. This routine returns the
|
|
|
|
/// "primary" DeclContext structure, which will contain the
|
|
|
|
/// information needed to perform name lookup into this context.
|
|
|
|
DeclContext *getPrimaryContext();
|
|
|
|
|
|
|
|
/// getLookupContext - Retrieve the innermost non-transparent
|
|
|
|
/// context of this context, which corresponds to the innermost
|
|
|
|
/// location from which name lookup can find the entities in this
|
|
|
|
/// context.
|
|
|
|
DeclContext *getLookupContext();
|
|
|
|
const DeclContext *getLookupContext() const {
|
|
|
|
return const_cast<DeclContext *>(this)->getLookupContext();
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// \brief Retrieve the nearest enclosing namespace context.
|
|
|
|
DeclContext *getEnclosingNamespaceContext();
|
|
|
|
const DeclContext *getEnclosingNamespaceContext() const {
|
|
|
|
return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// getNextContext - If this is a DeclContext that may have other
|
|
|
|
/// DeclContexts that are semantically connected but syntactically
|
|
|
|
/// different, such as C++ namespaces, this routine retrieves the
|
|
|
|
/// next DeclContext in the link. Iteration through the chain of
|
|
|
|
/// DeclContexts should begin at the primary DeclContext and
|
|
|
|
/// continue until this function returns NULL. For example, given:
|
|
|
|
/// @code
|
|
|
|
/// namespace N {
|
|
|
|
/// int x;
|
|
|
|
/// }
|
|
|
|
/// namespace N {
|
|
|
|
/// int y;
|
|
|
|
/// }
|
|
|
|
/// @endcode
|
|
|
|
/// The first occurrence of namespace N will be the primary
|
|
|
|
/// DeclContext. Its getNextContext will return the second
|
|
|
|
/// occurrence of namespace N.
|
|
|
|
DeclContext *getNextContext();
|
|
|
|
|
|
|
|
/// decl_iterator - Iterates through the declarations stored
|
|
|
|
/// within this context.
|
|
|
|
class decl_iterator {
|
|
|
|
/// Current - The current declaration.
|
|
|
|
Decl *Current;
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef Decl* value_type;
|
|
|
|
typedef Decl* reference;
|
|
|
|
typedef Decl* pointer;
|
|
|
|
typedef std::forward_iterator_tag iterator_category;
|
|
|
|
typedef std::ptrdiff_t difference_type;
|
|
|
|
|
|
|
|
decl_iterator() : Current(0) { }
|
|
|
|
explicit decl_iterator(Decl *C) : Current(C) { }
|
|
|
|
|
|
|
|
reference operator*() const { return Current; }
|
|
|
|
pointer operator->() const { return Current; }
|
|
|
|
|
|
|
|
decl_iterator& operator++() {
|
|
|
|
Current = Current->getNextDeclInContext();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
decl_iterator operator++(int) {
|
|
|
|
decl_iterator tmp(*this);
|
|
|
|
++(*this);
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
friend bool operator==(decl_iterator x, decl_iterator y) {
|
2009-06-02 17:58:47 +00:00
|
|
|
return x.Current == y.Current;
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
friend bool operator!=(decl_iterator x, decl_iterator y) {
|
2009-06-02 17:58:47 +00:00
|
|
|
return x.Current != y.Current;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// decls_begin/decls_end - Iterate over the declarations stored in
|
2009-10-14 18:03:49 +00:00
|
|
|
/// this context.
|
2009-07-04 13:58:54 +00:00
|
|
|
decl_iterator decls_begin() const;
|
|
|
|
decl_iterator decls_end() const;
|
|
|
|
bool decls_empty() const;
|
2009-06-02 17:58:47 +00:00
|
|
|
|
|
|
|
/// specific_decl_iterator - Iterates over a subrange of
|
|
|
|
/// declarations stored in a DeclContext, providing only those that
|
|
|
|
/// are of type SpecificDecl (or a class derived from it). This
|
|
|
|
/// iterator is used, for example, to provide iteration over just
|
|
|
|
/// the fields within a RecordDecl (with SpecificDecl = FieldDecl).
|
|
|
|
template<typename SpecificDecl>
|
|
|
|
class specific_decl_iterator {
|
|
|
|
/// Current - The current, underlying declaration iterator, which
|
|
|
|
/// will either be NULL or will point to a declaration of
|
|
|
|
/// type SpecificDecl.
|
|
|
|
DeclContext::decl_iterator Current;
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// SkipToNextDecl - Advances the current position up to the next
|
|
|
|
/// declaration of type SpecificDecl that also meets the criteria
|
|
|
|
/// required by Acceptable.
|
|
|
|
void SkipToNextDecl() {
|
|
|
|
while (*Current && !isa<SpecificDecl>(*Current))
|
|
|
|
++Current;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef SpecificDecl* value_type;
|
|
|
|
typedef SpecificDecl* reference;
|
|
|
|
typedef SpecificDecl* pointer;
|
|
|
|
typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
|
|
|
|
difference_type;
|
|
|
|
typedef std::forward_iterator_tag iterator_category;
|
|
|
|
|
|
|
|
specific_decl_iterator() : Current() { }
|
|
|
|
|
|
|
|
/// specific_decl_iterator - Construct a new iterator over a
|
|
|
|
/// subset of the declarations the range [C,
|
|
|
|
/// end-of-declarations). If A is non-NULL, it is a pointer to a
|
|
|
|
/// member function of SpecificDecl that should return true for
|
|
|
|
/// all of the SpecificDecl instances that will be in the subset
|
|
|
|
/// of iterators. For example, if you want Objective-C instance
|
|
|
|
/// methods, SpecificDecl will be ObjCMethodDecl and A will be
|
|
|
|
/// &ObjCMethodDecl::isInstanceMethod.
|
|
|
|
explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
|
|
|
|
SkipToNextDecl();
|
|
|
|
}
|
|
|
|
|
|
|
|
reference operator*() const { return cast<SpecificDecl>(*Current); }
|
|
|
|
pointer operator->() const { return cast<SpecificDecl>(*Current); }
|
|
|
|
|
|
|
|
specific_decl_iterator& operator++() {
|
|
|
|
++Current;
|
|
|
|
SkipToNextDecl();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
specific_decl_iterator operator++(int) {
|
|
|
|
specific_decl_iterator tmp(*this);
|
|
|
|
++(*this);
|
|
|
|
return tmp;
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
friend bool
|
|
|
|
operator==(const specific_decl_iterator& x, const specific_decl_iterator& y) {
|
|
|
|
return x.Current == y.Current;
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
|
|
|
friend bool
|
2009-06-02 17:58:47 +00:00
|
|
|
operator!=(const specific_decl_iterator& x, const specific_decl_iterator& y) {
|
|
|
|
return x.Current != y.Current;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Iterates over a filtered subrange of declarations stored
|
|
|
|
/// in a DeclContext.
|
|
|
|
///
|
|
|
|
/// This iterator visits only those declarations that are of type
|
|
|
|
/// SpecificDecl (or a class derived from it) and that meet some
|
|
|
|
/// additional run-time criteria. This iterator is used, for
|
|
|
|
/// example, to provide access to the instance methods within an
|
|
|
|
/// Objective-C interface (with SpecificDecl = ObjCMethodDecl and
|
|
|
|
/// Acceptable = ObjCMethodDecl::isInstanceMethod).
|
|
|
|
template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const>
|
|
|
|
class filtered_decl_iterator {
|
|
|
|
/// Current - The current, underlying declaration iterator, which
|
|
|
|
/// will either be NULL or will point to a declaration of
|
|
|
|
/// type SpecificDecl.
|
|
|
|
DeclContext::decl_iterator Current;
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// SkipToNextDecl - Advances the current position up to the next
|
|
|
|
/// declaration of type SpecificDecl that also meets the criteria
|
|
|
|
/// required by Acceptable.
|
|
|
|
void SkipToNextDecl() {
|
|
|
|
while (*Current &&
|
|
|
|
(!isa<SpecificDecl>(*Current) ||
|
|
|
|
(Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)())))
|
|
|
|
++Current;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef SpecificDecl* value_type;
|
|
|
|
typedef SpecificDecl* reference;
|
|
|
|
typedef SpecificDecl* pointer;
|
|
|
|
typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
|
|
|
|
difference_type;
|
|
|
|
typedef std::forward_iterator_tag iterator_category;
|
|
|
|
|
|
|
|
filtered_decl_iterator() : Current() { }
|
|
|
|
|
|
|
|
/// specific_decl_iterator - Construct a new iterator over a
|
|
|
|
/// subset of the declarations the range [C,
|
|
|
|
/// end-of-declarations). If A is non-NULL, it is a pointer to a
|
|
|
|
/// member function of SpecificDecl that should return true for
|
|
|
|
/// all of the SpecificDecl instances that will be in the subset
|
|
|
|
/// of iterators. For example, if you want Objective-C instance
|
|
|
|
/// methods, SpecificDecl will be ObjCMethodDecl and A will be
|
|
|
|
/// &ObjCMethodDecl::isInstanceMethod.
|
|
|
|
explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
|
|
|
|
SkipToNextDecl();
|
|
|
|
}
|
|
|
|
|
|
|
|
reference operator*() const { return cast<SpecificDecl>(*Current); }
|
|
|
|
pointer operator->() const { return cast<SpecificDecl>(*Current); }
|
|
|
|
|
|
|
|
filtered_decl_iterator& operator++() {
|
|
|
|
++Current;
|
|
|
|
SkipToNextDecl();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
filtered_decl_iterator operator++(int) {
|
|
|
|
filtered_decl_iterator tmp(*this);
|
|
|
|
++(*this);
|
|
|
|
return tmp;
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
friend bool
|
|
|
|
operator==(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
|
|
|
|
return x.Current == y.Current;
|
|
|
|
}
|
2009-10-14 18:03:49 +00:00
|
|
|
|
|
|
|
friend bool
|
2009-06-02 17:58:47 +00:00
|
|
|
operator!=(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
|
|
|
|
return x.Current != y.Current;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// @brief Add the declaration D into this context.
|
|
|
|
///
|
|
|
|
/// This routine should be invoked when the declaration D has first
|
|
|
|
/// been declared, to place D into the context where it was
|
|
|
|
/// (lexically) defined. Every declaration must be added to one
|
|
|
|
/// (and only one!) context, where it can be visited via
|
|
|
|
/// [decls_begin(), decls_end()). Once a declaration has been added
|
|
|
|
/// to its lexical context, the corresponding DeclContext owns the
|
|
|
|
/// declaration.
|
|
|
|
///
|
|
|
|
/// If D is also a NamedDecl, it will be made visible within its
|
|
|
|
/// semantic context via makeDeclVisibleInContext.
|
2009-07-04 13:58:54 +00:00
|
|
|
void addDecl(Decl *D);
|
2009-06-02 17:58:47 +00:00
|
|
|
|
2009-10-14 18:03:49 +00:00
|
|
|
/// @brief Add the declaration D to this context without modifying
|
|
|
|
/// any lookup tables.
|
|
|
|
///
|
|
|
|
/// This is useful for some operations in dependent contexts where
|
|
|
|
/// the semantic context might not be dependent; this basically
|
|
|
|
/// only happens with friends.
|
|
|
|
void addHiddenDecl(Decl *D);
|
|
|
|
|
2009-12-15 18:49:47 +00:00
|
|
|
/// @brief Removes a declaration from this context.
|
|
|
|
void removeDecl(Decl *D);
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// lookup_iterator - An iterator that provides access to the results
|
|
|
|
/// of looking up a name within this context.
|
|
|
|
typedef NamedDecl **lookup_iterator;
|
|
|
|
|
|
|
|
/// lookup_const_iterator - An iterator that provides non-mutable
|
|
|
|
/// access to the results of lookup up a name within this context.
|
|
|
|
typedef NamedDecl * const * lookup_const_iterator;
|
|
|
|
|
|
|
|
typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
|
|
|
|
typedef std::pair<lookup_const_iterator, lookup_const_iterator>
|
|
|
|
lookup_const_result;
|
|
|
|
|
|
|
|
/// lookup - Find the declarations (if any) with the given Name in
|
|
|
|
/// this context. Returns a range of iterators that contains all of
|
|
|
|
/// the declarations with this name, with object, function, member,
|
|
|
|
/// and enumerator names preceding any tag name. Note that this
|
|
|
|
/// routine will not look into parent contexts.
|
2009-07-04 13:58:54 +00:00
|
|
|
lookup_result lookup(DeclarationName Name);
|
|
|
|
lookup_const_result lookup(DeclarationName Name) const;
|
2009-06-02 17:58:47 +00:00
|
|
|
|
|
|
|
/// @brief Makes a declaration visible within this context.
|
|
|
|
///
|
|
|
|
/// This routine makes the declaration D visible to name lookup
|
|
|
|
/// within this context and, if this is a transparent context,
|
|
|
|
/// within its parent contexts up to the first enclosing
|
|
|
|
/// non-transparent context. Making a declaration visible within a
|
|
|
|
/// context does not transfer ownership of a declaration, and a
|
|
|
|
/// declaration can be visible in many contexts that aren't its
|
|
|
|
/// lexical context.
|
|
|
|
///
|
|
|
|
/// If D is a redeclaration of an existing declaration that is
|
|
|
|
/// visible from this context, as determined by
|
|
|
|
/// NamedDecl::declarationReplaces, the previous declaration will be
|
|
|
|
/// replaced with D.
|
2009-10-14 18:03:49 +00:00
|
|
|
///
|
|
|
|
/// @param Recoverable true if it's okay to not add this decl to
|
|
|
|
/// the lookup tables because it can be easily recovered by walking
|
|
|
|
/// the declaration chains.
|
|
|
|
void makeDeclVisibleInContext(NamedDecl *D, bool Recoverable = true);
|
2009-06-02 17:58:47 +00:00
|
|
|
|
|
|
|
/// udir_iterator - Iterates through the using-directives stored
|
|
|
|
/// within this context.
|
|
|
|
typedef UsingDirectiveDecl * const * udir_iterator;
|
2009-10-14 18:03:49 +00:00
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
|
|
|
|
|
2009-07-04 13:58:54 +00:00
|
|
|
udir_iterator_range getUsingDirectives() const;
|
2009-06-02 17:58:47 +00:00
|
|
|
|
2009-07-04 13:58:54 +00:00
|
|
|
udir_iterator using_directives_begin() const {
|
|
|
|
return getUsingDirectives().first;
|
2009-06-02 17:58:47 +00:00
|
|
|
}
|
|
|
|
|
2009-07-04 13:58:54 +00:00
|
|
|
udir_iterator using_directives_end() const {
|
|
|
|
return getUsingDirectives().second;
|
2009-06-02 17:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Low-level accessors
|
|
|
|
|
|
|
|
/// \brief Retrieve the internal representation of the lookup structure.
|
|
|
|
void* getLookupPtr() const { return LookupPtr; }
|
|
|
|
|
|
|
|
/// \brief Whether this DeclContext has external storage containing
|
|
|
|
/// additional declarations that are lexically in this context.
|
|
|
|
bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; }
|
|
|
|
|
|
|
|
/// \brief State whether this DeclContext has external storage for
|
|
|
|
/// declarations lexically in this context.
|
2009-10-14 18:03:49 +00:00
|
|
|
void setHasExternalLexicalStorage(bool ES = true) {
|
|
|
|
ExternalLexicalStorage = ES;
|
2009-06-02 17:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Whether this DeclContext has external storage containing
|
|
|
|
/// additional declarations that are visible in this context.
|
|
|
|
bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; }
|
|
|
|
|
|
|
|
/// \brief State whether this DeclContext has external storage for
|
|
|
|
/// declarations visible in this context.
|
2009-10-14 18:03:49 +00:00
|
|
|
void setHasExternalVisibleStorage(bool ES = true) {
|
|
|
|
ExternalVisibleStorage = ES;
|
2009-06-02 17:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool classof(const Decl *D);
|
|
|
|
static bool classof(const DeclContext *D) { return true; }
|
|
|
|
#define DECL_CONTEXT(Name) \
|
|
|
|
static bool classof(const Name##Decl *D) { return true; }
|
|
|
|
#include "clang/AST/DeclNodes.def"
|
|
|
|
|
2009-12-15 18:49:47 +00:00
|
|
|
void dumpDeclContext() const;
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
private:
|
2009-07-04 13:58:54 +00:00
|
|
|
void LoadLexicalDeclsFromExternalStorage() const;
|
|
|
|
void LoadVisibleDeclsFromExternalStorage() const;
|
2009-06-02 17:58:47 +00:00
|
|
|
|
2009-07-04 13:58:54 +00:00
|
|
|
void buildLookup(DeclContext *DCtx);
|
|
|
|
void makeDeclVisibleInContextImpl(NamedDecl *D);
|
2009-06-02 17:58:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
inline bool Decl::isTemplateParameter() const {
|
2010-01-23 11:10:26 +00:00
|
|
|
return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm ||
|
|
|
|
getKind() == TemplateTemplateParm;
|
2009-06-02 17:58:47 +00:00
|
|
|
}
|
|
|
|
|
2010-02-16 09:31:36 +00:00
|
|
|
|
|
|
|
// Specialization selected when ToTy is not a known subclass of DeclContext.
|
|
|
|
template <class ToTy,
|
|
|
|
bool IsKnownSubtype = ::llvm::is_base_of< DeclContext, ToTy>::value>
|
|
|
|
struct cast_convert_decl_context {
|
|
|
|
static const ToTy *doit(const DeclContext *Val) {
|
|
|
|
return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
|
|
|
|
}
|
|
|
|
|
|
|
|
static ToTy *doit(DeclContext *Val) {
|
|
|
|
return static_cast<ToTy*>(Decl::castFromDeclContext(Val));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Specialization selected when ToTy is a known subclass of DeclContext.
|
|
|
|
template <class ToTy>
|
|
|
|
struct cast_convert_decl_context<ToTy, true> {
|
|
|
|
static const ToTy *doit(const DeclContext *Val) {
|
|
|
|
return static_cast<const ToTy*>(Val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ToTy *doit(DeclContext *Val) {
|
|
|
|
return static_cast<ToTy*>(Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
} // end clang.
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
2010-02-16 09:31:36 +00:00
|
|
|
/// isa<T>(DeclContext*)
|
2009-06-02 17:58:47 +00:00
|
|
|
template<class ToTy>
|
|
|
|
struct isa_impl_wrap<ToTy,
|
|
|
|
const ::clang::DeclContext,const ::clang::DeclContext> {
|
|
|
|
static bool doit(const ::clang::DeclContext &Val) {
|
2010-02-16 09:31:36 +00:00
|
|
|
return ToTy::classofKind(Val.getDeclKind());
|
2009-06-02 17:58:47 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
template<class ToTy>
|
|
|
|
struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
|
|
|
|
: public isa_impl_wrap<ToTy,
|
|
|
|
const ::clang::DeclContext,const ::clang::DeclContext> {};
|
|
|
|
|
2010-02-16 09:31:36 +00:00
|
|
|
/// cast<T>(DeclContext*)
|
|
|
|
template<class ToTy>
|
|
|
|
struct cast_convert_val<ToTy,
|
|
|
|
const ::clang::DeclContext,const ::clang::DeclContext> {
|
|
|
|
static const ToTy &doit(const ::clang::DeclContext &Val) {
|
|
|
|
return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
template<class ToTy>
|
|
|
|
struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
|
|
|
|
static ToTy &doit(::clang::DeclContext &Val) {
|
|
|
|
return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
template<class ToTy>
|
|
|
|
struct cast_convert_val<ToTy,
|
|
|
|
const ::clang::DeclContext*, const ::clang::DeclContext*> {
|
|
|
|
static const ToTy *doit(const ::clang::DeclContext *Val) {
|
|
|
|
return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
template<class ToTy>
|
|
|
|
struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
|
|
|
|
static ToTy *doit(::clang::DeclContext *Val) {
|
|
|
|
return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-06-02 17:58:47 +00:00
|
|
|
/// Implement cast_convert_val for Decl -> DeclContext conversions.
|
|
|
|
template<class FromTy>
|
|
|
|
struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
|
|
|
|
static ::clang::DeclContext &doit(const FromTy &Val) {
|
|
|
|
return *FromTy::castToDeclContext(&Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class FromTy>
|
|
|
|
struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
|
|
|
|
static ::clang::DeclContext *doit(const FromTy *Val) {
|
|
|
|
return FromTy::castToDeclContext(Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class FromTy>
|
|
|
|
struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
|
|
|
|
static const ::clang::DeclContext &doit(const FromTy &Val) {
|
|
|
|
return *FromTy::castToDeclContext(&Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class FromTy>
|
|
|
|
struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
|
|
|
|
static const ::clang::DeclContext *doit(const FromTy *Val) {
|
|
|
|
return FromTy::castToDeclContext(Val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // end namespace llvm
|
|
|
|
|
|
|
|
#endif
|