| //===-- DeclCXX.h - Classes for representing C++ 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 C++ Decl subclasses. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CLANG_AST_DECLCXX_H |
| #define LLVM_CLANG_AST_DECLCXX_H |
| |
| #include "clang/AST/Expr.h" |
| #include "clang/AST/Decl.h" |
| #include "llvm/ADT/SmallVector.h" |
| |
| namespace clang { |
| |
| class ClassTemplateDecl; |
| class CXXRecordDecl; |
| class CXXConstructorDecl; |
| class CXXDestructorDecl; |
| class CXXConversionDecl; |
| class CXXMethodDecl; |
| class ClassTemplateSpecializationDecl; |
| |
| /// \brief Represents any kind of function declaration, whether it is a |
| /// concrete function or a function template. |
| class AnyFunctionDecl { |
| NamedDecl *Function; |
| |
| AnyFunctionDecl(NamedDecl *ND) : Function(ND) { } |
| |
| public: |
| AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { } |
| AnyFunctionDecl(FunctionTemplateDecl *FTD); |
| |
| /// \brief Implicily converts any function or function template into a |
| /// named declaration. |
| operator NamedDecl *() const { return Function; } |
| |
| /// \brief Retrieve the underlying function or function template. |
| NamedDecl *get() const { return Function; } |
| |
| static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) { |
| return AnyFunctionDecl(ND); |
| } |
| }; |
| |
| } // end namespace clang |
| |
| namespace llvm { |
| /// Implement simplify_type for AnyFunctionDecl, so that we can dyn_cast from |
| /// AnyFunctionDecl to any function or function template declaration. |
| template<> struct simplify_type<const ::clang::AnyFunctionDecl> { |
| typedef ::clang::NamedDecl* SimpleType; |
| static SimpleType getSimplifiedValue(const ::clang::AnyFunctionDecl &Val) { |
| return Val; |
| } |
| }; |
| template<> struct simplify_type< ::clang::AnyFunctionDecl> |
| : public simplify_type<const ::clang::AnyFunctionDecl> {}; |
| |
| // Provide PointerLikeTypeTraits for non-cvr pointers. |
| template<> |
| class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> { |
| public: |
| static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) { |
| return F.get(); |
| } |
| static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) { |
| return ::clang::AnyFunctionDecl::getFromNamedDecl( |
| static_cast< ::clang::NamedDecl*>(P)); |
| } |
| |
| enum { NumLowBitsAvailable = 2 }; |
| }; |
| |
| } // end namespace llvm |
| |
| namespace clang { |
| |
| /// OverloadedFunctionDecl - An instance of this class represents a |
| /// set of overloaded functions. All of the functions have the same |
| /// name and occur within the same scope. |
| /// |
| /// An OverloadedFunctionDecl has no ownership over the FunctionDecl |
| /// nodes it contains. Rather, the FunctionDecls are owned by the |
| /// enclosing scope (which also owns the OverloadedFunctionDecl |
| /// node). OverloadedFunctionDecl is used primarily to store a set of |
| /// overloaded functions for name lookup. |
| class OverloadedFunctionDecl : public NamedDecl { |
| protected: |
| OverloadedFunctionDecl(DeclContext *DC, DeclarationName N) |
| : NamedDecl(OverloadedFunction, DC, SourceLocation(), N) { } |
| |
| /// Functions - the set of overloaded functions contained in this |
| /// overload set. |
| llvm::SmallVector<AnyFunctionDecl, 4> Functions; |
| |
| // FIXME: This should go away when we stop using |
| // OverloadedFunctionDecl to store conversions in CXXRecordDecl. |
| friend class CXXRecordDecl; |
| |
| public: |
| typedef llvm::SmallVector<AnyFunctionDecl, 4>::iterator function_iterator; |
| typedef llvm::SmallVector<AnyFunctionDecl, 4>::const_iterator |
| function_const_iterator; |
| |
| static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC, |
| DeclarationName N); |
| |
| /// \brief Add a new overloaded function or function template to the set |
| /// of overloaded function templates. |
| void addOverload(AnyFunctionDecl F); |
| |
| function_iterator function_begin() { return Functions.begin(); } |
| function_iterator function_end() { return Functions.end(); } |
| function_const_iterator function_begin() const { return Functions.begin(); } |
| function_const_iterator function_end() const { return Functions.end(); } |
| |
| /// \brief Returns the number of overloaded functions stored in |
| /// this set. |
| unsigned size() const { return Functions.size(); } |
| |
| // Implement isa/cast/dyncast/etc. |
| static bool classof(const Decl *D) { |
| return D->getKind() == OverloadedFunction; |
| } |
| static bool classof(const OverloadedFunctionDecl *D) { return true; } |
| }; |
| |
| /// \brief Provides uniform iteration syntax for an overload set, function, |
| /// or function template. |
| class OverloadIterator { |
| /// \brief An overloaded function set, function declaration, or |
| /// function template declaration. |
| NamedDecl *D; |
| |
| /// \brief If the declaration is an overloaded function set, this is the |
| /// iterator pointing to the current position within that overloaded |
| /// function set. |
| OverloadedFunctionDecl::function_iterator Iter; |
| |
| public: |
| typedef AnyFunctionDecl value_type; |
| typedef value_type reference; |
| typedef NamedDecl *pointer; |
| typedef int difference_type; |
| typedef std::forward_iterator_tag iterator_category; |
| |
| OverloadIterator() : D(0) { } |
| |
| OverloadIterator(FunctionDecl *FD) : D(FD) { } |
| OverloadIterator(FunctionTemplateDecl *FTD) |
| : D(reinterpret_cast<NamedDecl*>(FTD)) { } |
| OverloadIterator(OverloadedFunctionDecl *Ovl) |
| : D(Ovl), Iter(Ovl->function_begin()) { } |
| |
| reference operator*() const; |
| |
| pointer operator->() const { return (**this).get(); } |
| |
| OverloadIterator &operator++(); |
| |
| OverloadIterator operator++(int) { |
| OverloadIterator Temp(*this); |
| ++(*this); |
| return Temp; |
| } |
| |
| bool Equals(const OverloadIterator &Other) const; |
| }; |
| |
| inline bool operator==(const OverloadIterator &X, const OverloadIterator &Y) { |
| return X.Equals(Y); |
| } |
| |
| inline bool operator!=(const OverloadIterator &X, const OverloadIterator &Y) { |
| return !(X == Y); |
| } |
| |
| /// CXXBaseSpecifier - A base class of a C++ class. |
| /// |
| /// Each CXXBaseSpecifier represents a single, direct base class (or |
| /// struct) of a C++ class (or struct). It specifies the type of that |
| /// base class, whether it is a virtual or non-virtual base, and what |
| /// level of access (public, protected, private) is used for the |
| /// derivation. For example: |
| /// |
| /// @code |
| /// class A { }; |
| /// class B { }; |
| /// class C : public virtual A, protected B { }; |
| /// @endcode |
| /// |
| /// In this code, C will have two CXXBaseSpecifiers, one for "public |
| /// virtual A" and the other for "protected B". |
| class CXXBaseSpecifier { |
| /// Range - The source code range that covers the full base |
| /// specifier, including the "virtual" (if present) and access |
| /// specifier (if present). |
| SourceRange Range; |
| |
| /// Virtual - Whether this is a virtual base class or not. |
| bool Virtual : 1; |
| |
| /// BaseOfClass - Whether this is the base of a class (true) or of a |
| /// struct (false). This determines the mapping from the access |
| /// specifier as written in the source code to the access specifier |
| /// used for semantic analysis. |
| bool BaseOfClass : 1; |
| |
| /// Access - Access specifier as written in the source code (which |
| /// may be AS_none). The actual type of data stored here is an |
| /// AccessSpecifier, but we use "unsigned" here to work around a |
| /// VC++ bug. |
| unsigned Access : 2; |
| |
| /// BaseType - The type of the base class. This will be a class or |
| /// struct (or a typedef of such). |
| QualType BaseType; |
| |
| public: |
| CXXBaseSpecifier() { } |
| |
| CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, QualType T) |
| : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseType(T) { } |
| |
| /// getSourceRange - Retrieves the source range that contains the |
| /// entire base specifier. |
| SourceRange getSourceRange() const { return Range; } |
| |
| /// isVirtual - Determines whether the base class is a virtual base |
| /// class (or not). |
| bool isVirtual() const { return Virtual; } |
| |
| /// getAccessSpecifier - Returns the access specifier for this base |
| /// specifier. This is the actual base specifier as used for |
| /// semantic analysis, so the result can never be AS_none. To |
| /// retrieve the access specifier as written in the source code, use |
| /// getAccessSpecifierAsWritten(). |
| AccessSpecifier getAccessSpecifier() const { |
| if ((AccessSpecifier)Access == AS_none) |
| return BaseOfClass? AS_private : AS_public; |
| else |
| return (AccessSpecifier)Access; |
| } |
| |
| /// getAccessSpecifierAsWritten - Retrieves the access specifier as |
| /// written in the source code (which may mean that no access |
| /// specifier was explicitly written). Use getAccessSpecifier() to |
| /// retrieve the access specifier for use in semantic analysis. |
| AccessSpecifier getAccessSpecifierAsWritten() const { |
| return (AccessSpecifier)Access; |
| } |
| |
| /// getType - Retrieves the type of the base class. This type will |
| /// always be an unqualified class type. |
| QualType getType() const { return BaseType; } |
| }; |
| |
| /// CXXRecordDecl - Represents a C++ struct/union/class. |
| /// FIXME: This class will disappear once we've properly taught RecordDecl |
| /// to deal with C++-specific things. |
| class CXXRecordDecl : public RecordDecl { |
| /// UserDeclaredConstructor - True when this class has a |
| /// user-declared constructor. |
| bool UserDeclaredConstructor : 1; |
| |
| /// UserDeclaredCopyConstructor - True when this class has a |
| /// user-declared copy constructor. |
| bool UserDeclaredCopyConstructor : 1; |
| |
| /// UserDeclaredCopyAssignment - True when this class has a |
| /// user-declared copy assignment operator. |
| bool UserDeclaredCopyAssignment : 1; |
| |
| /// UserDeclaredDestructor - True when this class has a |
| /// user-declared destructor. |
| bool UserDeclaredDestructor : 1; |
| |
| /// Aggregate - True when this class is an aggregate. |
| bool Aggregate : 1; |
| |
| /// PlainOldData - True when this class is a POD-type. |
| bool PlainOldData : 1; |
| |
| /// Polymorphic - True when this class is polymorphic, i.e. has at least one |
| /// virtual member or derives from a polymorphic class. |
| bool Polymorphic : 1; |
| |
| /// Abstract - True when this class is abstract, i.e. has at least one |
| /// pure virtual function, (that can come from a base class). |
| bool Abstract : 1; |
| |
| /// HasTrivialConstructor - True when this class has a trivial constructor. |
| /// |
| /// C++ [class.ctor]p5. A constructor is trivial if it is an |
| /// implicitly-declared default constructor and if: |
| /// * its class has no virtual functions and no virtual base classes, and |
| /// * all the direct base classes of its class have trivial constructors, and |
| /// * for all the nonstatic data members of its class that are of class type |
| /// (or array thereof), each such class has a trivial constructor. |
| bool HasTrivialConstructor : 1; |
| |
| /// HasTrivialCopyConstructor - True when this class has a trivial copy |
| /// constructor. |
| /// |
| /// C++ [class.copy]p6. A copy constructor for class X is trivial |
| /// if it is implicitly declared and if |
| /// * class X has no virtual functions and no virtual base classes, and |
| /// * each direct base class of X has a trivial copy constructor, and |
| /// * for all the nonstatic data members of X that are of class type (or |
| /// array thereof), each such class type has a trivial copy constructor; |
| /// otherwise the copy constructor is non-trivial. |
| bool HasTrivialCopyConstructor : 1; |
| |
| /// HasTrivialCopyAssignment - True when this class has a trivial copy |
| /// assignment operator. |
| /// |
| /// C++ [class.copy]p11. A copy assignment operator for class X is |
| /// trivial if it is implicitly declared and if |
| /// * class X has no virtual functions and no virtual base classes, and |
| /// * each direct base class of X has a trivial copy assignment operator, and |
| /// * for all the nonstatic data members of X that are of class type (or |
| /// array thereof), each such class type has a trivial copy assignment |
| /// operator; |
| /// otherwise the copy assignment operator is non-trivial. |
| bool HasTrivialCopyAssignment : 1; |
| |
| /// HasTrivialDestructor - True when this class has a trivial destructor. |
| /// |
| /// C++ [class.dtor]p3. A destructor is trivial if it is an |
| /// implicitly-declared destructor and if: |
| /// * all of the direct base classes of its class have trivial destructors |
| /// and |
| /// * for all of the non-static data members of its class that are of class |
| /// type (or array thereof), each such class has a trivial destructor. |
| bool HasTrivialDestructor : 1; |
| |
| /// Bases - Base classes of this class. |
| /// FIXME: This is wasted space for a union. |
| CXXBaseSpecifier *Bases; |
| |
| /// NumBases - The number of base class specifiers in Bases. |
| unsigned NumBases; |
| |
| /// VBases - direct and indirect virtual base classes of this class. |
| CXXBaseSpecifier *VBases; |
| |
| /// NumVBases - The number of virtual base class specifiers in VBases. |
| unsigned NumVBases; |
| |
| /// Conversions - Overload set containing the conversion functions |
| /// of this C++ class (but not its inherited conversion |
| /// functions). Each of the entries in this overload set is a |
| /// CXXConversionDecl. |
| OverloadedFunctionDecl Conversions; |
| |
| /// \brief The template or declaration that this declaration |
| /// describes or was instantiated from, respectively. |
| /// |
| /// For non-templates, this value will be NULL. For record |
| /// declarations that describe a class template, this will be a |
| /// pointer to a ClassTemplateDecl. For member |
| /// classes of class template specializations, this will be the |
| /// RecordDecl from which the member class was instantiated. |
| llvm::PointerUnion<ClassTemplateDecl*, CXXRecordDecl*> |
| TemplateOrInstantiation; |
| |
| protected: |
| CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, |
| SourceLocation L, IdentifierInfo *Id, |
| CXXRecordDecl *PrevDecl, |
| SourceLocation TKL = SourceLocation()); |
| |
| ~CXXRecordDecl(); |
| |
| public: |
| /// base_class_iterator - Iterator that traverses the base classes |
| /// of a class. |
| typedef CXXBaseSpecifier* base_class_iterator; |
| |
| /// base_class_const_iterator - Iterator that traverses the base |
| /// classes of a class. |
| typedef const CXXBaseSpecifier* base_class_const_iterator; |
| |
| static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC, |
| SourceLocation L, IdentifierInfo *Id, |
| SourceLocation TKL = SourceLocation(), |
| CXXRecordDecl* PrevDecl=0, |
| bool DelayTypeCreation = false); |
| |
| virtual void Destroy(ASTContext& C); |
| |
| bool isDynamicClass() const { |
| return Polymorphic || NumVBases!=0; |
| } |
| |
| /// setBases - Sets the base classes of this struct or class. |
| void setBases(ASTContext &C, |
| CXXBaseSpecifier const * const *Bases, unsigned NumBases); |
| |
| /// getNumBases - Retrieves the number of base classes of this |
| /// class. |
| unsigned getNumBases() const { return NumBases; } |
| |
| base_class_iterator bases_begin() { return Bases; } |
| base_class_const_iterator bases_begin() const { return Bases; } |
| base_class_iterator bases_end() { return Bases + NumBases; } |
| base_class_const_iterator bases_end() const { return Bases + NumBases; } |
| |
| /// getNumVBases - Retrieves the number of virtual base classes of this |
| /// class. |
| unsigned getNumVBases() const { return NumVBases; } |
| |
| base_class_iterator vbases_begin() { return VBases; } |
| base_class_const_iterator vbases_begin() const { return VBases; } |
| base_class_iterator vbases_end() { return VBases + NumVBases; } |
| base_class_const_iterator vbases_end() const { return VBases + NumVBases; } |
| |
| /// Iterator access to method members. The method iterator visits |
| /// all method members of the class, including non-instance methods, |
| /// special methods, etc. |
| typedef specific_decl_iterator<CXXMethodDecl> method_iterator; |
| |
| /// method_begin - Method begin iterator. Iterates in the order the methods |
| /// were declared. |
| method_iterator method_begin() const { |
| return method_iterator(decls_begin()); |
| } |
| /// method_end - Method end iterator. |
| method_iterator method_end() const { |
| return method_iterator(decls_end()); |
| } |
| |
| /// Iterator access to constructor members. |
| typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator; |
| |
| ctor_iterator ctor_begin() const { |
| return ctor_iterator(decls_begin()); |
| } |
| ctor_iterator ctor_end() const { |
| return ctor_iterator(decls_end()); |
| } |
| |
| /// hasConstCopyConstructor - Determines whether this class has a |
| /// copy constructor that accepts a const-qualified argument. |
| bool hasConstCopyConstructor(ASTContext &Context) const; |
| |
| /// getCopyConstructor - Returns the copy constructor for this class |
| CXXConstructorDecl *getCopyConstructor(ASTContext &Context, |
| unsigned TypeQuals) const; |
| |
| /// hasConstCopyAssignment - Determines whether this class has a |
| /// copy assignment operator that accepts a const-qualified argument. |
| bool hasConstCopyAssignment(ASTContext &Context) 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. |
| void addedConstructor(ASTContext &Context, CXXConstructorDecl *ConDecl); |
| |
| /// hasUserDeclaredConstructor - Whether this class has any |
| /// user-declared constructors. When true, a default constructor |
| /// will not be implicitly declared. |
| bool hasUserDeclaredConstructor() const { return UserDeclaredConstructor; } |
| |
| /// hasUserDeclaredCopyConstructor - Whether this class has a |
| /// user-declared copy constructor. When false, a copy constructor |
| /// will be implicitly declared. |
| bool hasUserDeclaredCopyConstructor() const { |
| return UserDeclaredCopyConstructor; |
| } |
| |
| /// 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. |
| void addedAssignmentOperator(ASTContext &Context, CXXMethodDecl *OpDecl); |
| |
| /// hasUserDeclaredCopyAssignment - Whether this class has a |
| /// user-declared copy assignment operator. When false, a copy |
| /// assigment operator will be implicitly declared. |
| bool hasUserDeclaredCopyAssignment() const { |
| return UserDeclaredCopyAssignment; |
| } |
| |
| /// hasUserDeclaredDestructor - Whether this class has a |
| /// user-declared destructor. When false, a destructor will be |
| /// implicitly declared. |
| bool hasUserDeclaredDestructor() const { return UserDeclaredDestructor; } |
| |
| /// setUserDeclaredDestructor - Set whether this class has a |
| /// user-declared destructor. If not set by the time the class is |
| /// fully defined, a destructor will be implicitly declared. |
| void setUserDeclaredDestructor(bool UCD) { |
| UserDeclaredDestructor = UCD; |
| } |
| |
| /// getConversions - Retrieve the overload set containing all of the |
| /// conversion functions in this class. |
| OverloadedFunctionDecl *getConversionFunctions() { |
| return &Conversions; |
| } |
| const OverloadedFunctionDecl *getConversionFunctions() const { |
| return &Conversions; |
| } |
| |
| /// addConversionFunction - Add a new conversion function to the |
| /// list of conversion functions. |
| void addConversionFunction(ASTContext &Context, CXXConversionDecl *ConvDecl); |
| |
| /// isAggregate - Whether this class is an aggregate (C++ |
| /// [dcl.init.aggr]), which is a class with no user-declared |
| /// constructors, no private or protected non-static data members, |
| /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1). |
| bool isAggregate() const { return Aggregate; } |
| |
| /// setAggregate - Set whether this class is an aggregate (C++ |
| /// [dcl.init.aggr]). |
| void setAggregate(bool Agg) { Aggregate = Agg; } |
| |
| /// 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 |
| /// user-defined destructor. |
| bool isPOD() const { return PlainOldData; } |
| |
| /// setPOD - Set whether this class is a POD-type (C++ [class]p4). |
| void setPOD(bool POD) { PlainOldData = POD; } |
| |
| /// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]), |
| /// which means that the class contains or inherits a virtual function. |
| bool isPolymorphic() const { return Polymorphic; } |
| |
| /// setPolymorphic - Set whether this class is polymorphic (C++ |
| /// [class.virtual]). |
| void setPolymorphic(bool Poly) { Polymorphic = Poly; } |
| |
| /// isAbstract - Whether this class is abstract (C++ [class.abstract]), |
| /// which means that the class contains or inherits a pure virtual function. |
| bool isAbstract() const { return Abstract; } |
| |
| /// setAbstract - Set whether this class is abstract (C++ [class.abstract]) |
| void setAbstract(bool Abs) { Abstract = Abs; } |
| |
| // hasTrivialConstructor - Whether this class has a trivial constructor |
| // (C++ [class.ctor]p5) |
| bool hasTrivialConstructor() const { return HasTrivialConstructor; } |
| |
| // setHasTrivialConstructor - Set whether this class has a trivial constructor |
| // (C++ [class.ctor]p5) |
| void setHasTrivialConstructor(bool TC) { HasTrivialConstructor = TC; } |
| |
| // hasTrivialCopyConstructor - Whether this class has a trivial copy |
| // constructor (C++ [class.copy]p6) |
| bool hasTrivialCopyConstructor() const { return HasTrivialCopyConstructor; } |
| |
| // setHasTrivialCopyConstructor - Set whether this class has a trivial |
| // copy constructor (C++ [class.copy]p6) |
| void setHasTrivialCopyConstructor(bool TC) { HasTrivialCopyConstructor = TC; } |
| |
| // hasTrivialCopyAssignment - Whether this class has a trivial copy |
| // assignment operator (C++ [class.copy]p11) |
| bool hasTrivialCopyAssignment() const { return HasTrivialCopyAssignment; } |
| |
| // setHasTrivialCopyAssignment - Set whether this class has a |
| // trivial copy assignment operator (C++ [class.copy]p11) |
| void setHasTrivialCopyAssignment(bool TC) { HasTrivialCopyAssignment = TC; } |
| |
| // hasTrivialDestructor - Whether this class has a trivial destructor |
| // (C++ [class.dtor]p3) |
| bool hasTrivialDestructor() const { return HasTrivialDestructor; } |
| |
| // setHasTrivialDestructor - Set whether this class has a trivial destructor |
| // (C++ [class.dtor]p3) |
| void setHasTrivialDestructor(bool TC) { HasTrivialDestructor = TC; } |
| |
| /// \brief If this record is an instantiation of a member class, |
| /// retrieves the member class from which it was instantiated. |
| /// |
| /// This routine will return non-NULL for (non-templated) member |
| /// classes of class templates. For example, given: |
| /// |
| /// \code |
| /// template<typename T> |
| /// struct X { |
| /// struct A { }; |
| /// }; |
| /// \endcode |
| /// |
| /// The declaration for X<int>::A is a (non-templated) CXXRecordDecl |
| /// whose parent is the class template specialization X<int>. For |
| /// this declaration, getInstantiatedFromMemberClass() will return |
| /// the CXXRecordDecl X<T>::A. When a complete definition of |
| /// X<int>::A is required, it will be instantiated from the |
| /// declaration returned by getInstantiatedFromMemberClass(). |
| CXXRecordDecl *getInstantiatedFromMemberClass() const { |
| return TemplateOrInstantiation.dyn_cast<CXXRecordDecl*>(); |
| } |
| |
| /// \brief Specify that this record is an instantiation of the |
| /// member class RD. |
| void setInstantiationOfMemberClass(CXXRecordDecl *RD) { |
| TemplateOrInstantiation = RD; |
| } |
| |
| /// \brief Retrieves the class template that is described by this |
| /// class declaration. |
| /// |
| /// Every class template is represented as a ClassTemplateDecl and a |
| /// CXXRecordDecl. The former contains template properties (such as |
| /// the template parameter lists) while the latter contains the |
| /// actual description of the template's |
| /// contents. ClassTemplateDecl::getTemplatedDecl() retrieves the |
| /// CXXRecordDecl that from a ClassTemplateDecl, while |
| /// getDescribedClassTemplate() retrieves the ClassTemplateDecl from |
| /// a CXXRecordDecl. |
| ClassTemplateDecl *getDescribedClassTemplate() const { |
| return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl*>(); |
| } |
| |
| void setDescribedClassTemplate(ClassTemplateDecl *Template) { |
| TemplateOrInstantiation = Template; |
| } |
| |
| /// getDefaultConstructor - Returns the default constructor for this class |
| CXXConstructorDecl *getDefaultConstructor(ASTContext &Context); |
| |
| /// getDestructor - Returns the destructor decl for this class. |
| const CXXDestructorDecl *getDestructor(ASTContext &Context); |
| |
| /// isLocalClass - If the class is a local class [class.local], returns |
| /// the enclosing function declaration. |
| const FunctionDecl *isLocalClass() const { |
| if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext())) |
| return RD->isLocalClass(); |
| |
| return dyn_cast<FunctionDecl>(getDeclContext()); |
| } |
| |
| /// viewInheritance - Renders and displays an inheritance diagram |
| /// for this C++ class and all of its base classes (transitively) using |
| /// GraphViz. |
| void viewInheritance(ASTContext& Context) const; |
| |
| static bool classof(const Decl *D) { |
| return D->getKind() == CXXRecord || |
| D->getKind() == ClassTemplateSpecialization || |
| D->getKind() == ClassTemplatePartialSpecialization; |
| } |
| static bool classof(const CXXRecordDecl *D) { return true; } |
| static bool classof(const ClassTemplateSpecializationDecl *D) { |
| return true; |
| } |
| }; |
| |
| /// CXXMethodDecl - Represents a static or instance method of a |
| /// struct/union/class. |
| class CXXMethodDecl : public FunctionDecl { |
| protected: |
| CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L, |
| DeclarationName N, QualType T, |
| bool isStatic, bool isInline) |
| : FunctionDecl(DK, RD, L, N, T, (isStatic ? Static : None), |
| isInline) {} |
| |
| public: |
| static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD, |
| SourceLocation L, DeclarationName N, |
| QualType T, bool isStatic = false, |
| bool isInline = false); |
| |
| bool isStatic() const { return getStorageClass() == Static; } |
| bool isInstance() const { return !isStatic(); } |
| |
| bool isVirtual() const { |
| return isVirtualAsWritten() || |
| (begin_overridden_methods() != end_overridden_methods()); |
| } |
| |
| /// |
| void addOverriddenMethod(const CXXMethodDecl *MD); |
| |
| typedef const CXXMethodDecl ** method_iterator; |
| |
| method_iterator begin_overridden_methods() const; |
| method_iterator end_overridden_methods() const; |
| |
| /// getParent - Returns the parent of this method declaration, which |
| /// is the class in which this method is defined. |
| const CXXRecordDecl *getParent() const { |
| return cast<CXXRecordDecl>(FunctionDecl::getParent()); |
| } |
| |
| /// getParent - Returns the parent of this method declaration, which |
| /// is the class in which this method is defined. |
| CXXRecordDecl *getParent() { |
| return const_cast<CXXRecordDecl *>( |
| cast<CXXRecordDecl>(FunctionDecl::getParent())); |
| } |
| |
| /// getThisType - Returns the type of 'this' pointer. |
| /// Should only be called for instance methods. |
| QualType getThisType(ASTContext &C) const; |
| |
| unsigned getTypeQualifiers() const { |
| return getType()->getAsFunctionProtoType()->getTypeQuals(); |
| } |
| |
| // Implement isa/cast/dyncast/etc. |
| static bool classof(const Decl *D) { |
| return D->getKind() >= CXXMethod && D->getKind() <= CXXConversion; |
| } |
| static bool classof(const CXXMethodDecl *D) { return true; } |
| }; |
| |
| /// CXXBaseOrMemberInitializer - Represents a C++ base or member |
| /// initializer, which is part of a constructor initializer that |
| /// initializes one non-static member variable or one base class. For |
| /// example, in the following, both 'A(a)' and 'f(3.14159)' are member |
| /// initializers: |
| /// |
| /// @code |
| /// class A { }; |
| /// class B : public A { |
| /// float f; |
| /// public: |
| /// B(A& a) : A(a), f(3.14159) { } |
| /// }; |
| /// @endcode |
| class CXXBaseOrMemberInitializer { |
| /// BaseOrMember - This points to the entity being initialized, |
| /// which is either a base class (a Type) or a non-static data |
| /// member. When the low bit is 1, it's a base |
| /// class; when the low bit is 0, it's a member. |
| uintptr_t BaseOrMember; |
| |
| /// Args - The arguments used to initialize the base or member. |
| Stmt **Args; |
| unsigned NumArgs; |
| |
| /// CtorToCall - For a base or member needing a constructor for their |
| /// initialization, this is the constructor to call. |
| CXXConstructorDecl *CtorToCall; |
| |
| /// IdLoc - Location of the id in ctor-initializer list. |
| SourceLocation IdLoc; |
| |
| public: |
| /// CXXBaseOrMemberInitializer - Creates a new base-class initializer. |
| explicit |
| CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs, |
| CXXConstructorDecl *C, |
| SourceLocation L); |
| |
| /// CXXBaseOrMemberInitializer - Creates a new member initializer. |
| explicit |
| CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs, |
| CXXConstructorDecl *C, |
| SourceLocation L); |
| |
| /// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer. |
| ~CXXBaseOrMemberInitializer(); |
| |
| /// arg_iterator - Iterates through the member initialization |
| /// arguments. |
| typedef ExprIterator arg_iterator; |
| |
| /// arg_const_iterator - Iterates through the member initialization |
| /// arguments. |
| typedef ConstExprIterator const_arg_iterator; |
| |
| /// getBaseOrMember - get the generic 'member' representing either the field |
| /// or a base class. |
| void* getBaseOrMember() const { return reinterpret_cast<void*>(BaseOrMember); } |
| |
| /// isBaseInitializer - Returns true when this initializer is |
| /// initializing a base class. |
| bool isBaseInitializer() const { return (BaseOrMember & 0x1) != 0; } |
| |
| /// isMemberInitializer - Returns true when this initializer is |
| /// initializing a non-static data member. |
| bool isMemberInitializer() const { return (BaseOrMember & 0x1) == 0; } |
| |
| /// getBaseClass - If this is a base class initializer, returns the |
| /// type used to specify the initializer. The resulting type will be |
| /// a class type or a typedef of a class type. If this is not a base |
| /// class initializer, returns NULL. |
| Type *getBaseClass() { |
| if (isBaseInitializer()) |
| return reinterpret_cast<Type*>(BaseOrMember & ~0x01); |
| else |
| return 0; |
| } |
| |
| /// getBaseClass - If this is a base class initializer, returns the |
| /// type used to specify the initializer. The resulting type will be |
| /// a class type or a typedef of a class type. If this is not a base |
| /// class initializer, returns NULL. |
| const Type *getBaseClass() const { |
| if (isBaseInitializer()) |
| return reinterpret_cast<const Type*>(BaseOrMember & ~0x01); |
| else |
| return 0; |
| } |
| |
| /// getMember - If this is a member initializer, returns the |
| /// declaration of the non-static data member being |
| /// initialized. Otherwise, returns NULL. |
| FieldDecl *getMember() { |
| if (isMemberInitializer()) |
| return reinterpret_cast<FieldDecl *>(BaseOrMember); |
| else |
| return 0; |
| } |
| |
| const CXXConstructorDecl *getConstructor() const { return CtorToCall; } |
| |
| SourceLocation getSourceLocation() const { return IdLoc; } |
| |
| /// arg_begin() - Retrieve an iterator to the first initializer argument. |
| arg_iterator arg_begin() { return Args; } |
| /// arg_begin() - Retrieve an iterator to the first initializer argument. |
| const_arg_iterator const_arg_begin() const { return Args; } |
| |
| /// arg_end() - Retrieve an iterator past the last initializer argument. |
| arg_iterator arg_end() { return Args + NumArgs; } |
| /// arg_end() - Retrieve an iterator past the last initializer argument. |
| const_arg_iterator const_arg_end() const { return Args + NumArgs; } |
| |
| /// getNumArgs - Determine the number of arguments used to |
| /// initialize the member or base. |
| unsigned getNumArgs() const { return NumArgs; } |
| }; |
| |
| /// CXXConstructorDecl - Represents a C++ constructor within a |
| /// class. For example: |
| /// |
| /// @code |
| /// class X { |
| /// public: |
| /// explicit X(int); // represented by a CXXConstructorDecl. |
| /// }; |
| /// @endcode |
| class CXXConstructorDecl : public CXXMethodDecl { |
| /// Explicit - Whether this constructor is explicit. |
| bool Explicit : 1; |
| |
| /// ImplicitlyDefined - Whether this constructor was implicitly |
| /// defined by the compiler. When false, the constructor was defined |
| /// by the user. In C++03, this flag will have the same value as |
| /// Implicit. In C++0x, however, a constructor that is |
| /// explicitly defaulted (i.e., defined with " = default") will have |
| /// @c !Implicit && ImplicitlyDefined. |
| bool ImplicitlyDefined : 1; |
| |
| /// Support for base and member initializers. |
| /// BaseOrMemberInitializers - The arguments used to initialize the base |
| /// or member. |
| CXXBaseOrMemberInitializer **BaseOrMemberInitializers; |
| unsigned NumBaseOrMemberInitializers; |
| |
| CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L, |
| DeclarationName N, QualType T, |
| bool isExplicit, bool isInline, bool isImplicitlyDeclared) |
| : CXXMethodDecl(CXXConstructor, RD, L, N, T, false, isInline), |
| Explicit(isExplicit), ImplicitlyDefined(false), |
| BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) { |
| setImplicit(isImplicitlyDeclared); |
| } |
| virtual void Destroy(ASTContext& C); |
| |
| public: |
| static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, |
| SourceLocation L, DeclarationName N, |
| QualType T, bool isExplicit, |
| bool isInline, bool isImplicitlyDeclared); |
| |
| /// isExplicit - Whether this constructor was marked "explicit" or not. |
| bool isExplicit() const { return Explicit; } |
| |
| /// isImplicitlyDefined - Whether this constructor was implicitly |
| /// defined. If false, then this constructor was defined by the |
| /// user. This operation can only be invoked if the constructor has |
| /// already been defined. |
| bool isImplicitlyDefined(ASTContext &C) const { |
| assert(isThisDeclarationADefinition() && |
| "Can only get the implicit-definition flag once the " |
| "constructor has been defined"); |
| return ImplicitlyDefined; |
| } |
| |
| /// setImplicitlyDefined - Set whether this constructor was |
| /// implicitly defined or not. |
| void setImplicitlyDefined(bool ID) { |
| assert(isThisDeclarationADefinition() && |
| "Can only set the implicit-definition flag once the constructor " |
| "has been defined"); |
| ImplicitlyDefined = ID; |
| } |
| |
| /// init_iterator - Iterates through the member/base initializer list. |
| typedef CXXBaseOrMemberInitializer **init_iterator; |
| |
| /// init_const_iterator - Iterates through the memberbase initializer list. |
| typedef CXXBaseOrMemberInitializer * const * init_const_iterator; |
| |
| /// init_begin() - Retrieve an iterator to the first initializer. |
| init_iterator init_begin() { return BaseOrMemberInitializers; } |
| /// begin() - Retrieve an iterator to the first initializer. |
| init_const_iterator init_begin() const { return BaseOrMemberInitializers; } |
| |
| /// init_end() - Retrieve an iterator past the last initializer. |
| init_iterator init_end() { |
| return BaseOrMemberInitializers + NumBaseOrMemberInitializers; |
| } |
| /// end() - Retrieve an iterator past the last initializer. |
| init_const_iterator init_end() const { |
| return BaseOrMemberInitializers + NumBaseOrMemberInitializers; |
| } |
| |
| /// getNumArgs - Determine the number of arguments used to |
| /// initialize the member or base. |
| unsigned getNumBaseOrMemberInitializers() const { |
| return NumBaseOrMemberInitializers; |
| } |
| |
| void setBaseOrMemberInitializers(ASTContext &C, |
| CXXBaseOrMemberInitializer **Initializers, |
| unsigned NumInitializers, |
| llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases, |
| llvm::SmallVectorImpl<FieldDecl *>&Members); |
| |
| /// isDefaultConstructor - Whether this constructor is a default |
| /// constructor (C++ [class.ctor]p5), which can be used to |
| /// default-initialize a class of this type. |
| bool isDefaultConstructor() const; |
| |
| /// isCopyConstructor - Whether this constructor is a copy |
| /// constructor (C++ [class.copy]p2, which can be used to copy the |
| /// class. @p TypeQuals will be set to the qualifiers on the |
| /// argument type. For example, @p TypeQuals would be set to @c |
| /// QualType::Const for the following copy constructor: |
| /// |
| /// @code |
| /// class X { |
| /// public: |
| /// X(const X&); |
| /// }; |
| /// @endcode |
| bool isCopyConstructor(ASTContext &Context, unsigned &TypeQuals) const; |
| |
| /// isCopyConstructor - Whether this constructor is a copy |
| /// constructor (C++ [class.copy]p2, which can be used to copy the |
| /// class. |
| bool isCopyConstructor(ASTContext &Context) const { |
| unsigned TypeQuals = 0; |
| return isCopyConstructor(Context, TypeQuals); |
| } |
| |
| /// isConvertingConstructor - Whether this constructor is a |
| /// converting constructor (C++ [class.conv.ctor]), which can be |
| /// used for user-defined conversions. |
| bool isConvertingConstructor() const; |
| |
| // Implement isa/cast/dyncast/etc. |
| static bool classof(const Decl *D) { |
| return D->getKind() == CXXConstructor; |
| } |
| static bool classof(const CXXConstructorDecl *D) { return true; } |
| }; |
| |
| /// CXXDestructorDecl - Represents a C++ destructor within a |
| /// class. For example: |
| /// |
| /// @code |
| /// class X { |
| /// public: |
| /// ~X(); // represented by a CXXDestructorDecl. |
| /// }; |
| /// @endcode |
| class CXXDestructorDecl : public CXXMethodDecl { |
| enum KindOfObjectToDestroy { |
| VBASE = 0x1, |
| DRCTNONVBASE = 0x2, |
| ANYBASE = 0x3 |
| }; |
| |
| /// ImplicitlyDefined - Whether this destructor was implicitly |
| /// defined by the compiler. When false, the destructor was defined |
| /// by the user. In C++03, this flag will have the same value as |
| /// Implicit. In C++0x, however, a destructor that is |
| /// explicitly defaulted (i.e., defined with " = default") will have |
| /// @c !Implicit && ImplicitlyDefined. |
| bool ImplicitlyDefined : 1; |
| |
| /// Support for base and member destruction. |
| /// BaseOrMemberDestructions - The arguments used to destruct the base |
| /// or member. Each uintptr_t value represents one of base classes (either |
| /// virtual or direct non-virtual base), or non-static data member |
| /// to be destroyed. The low two bits encode the kind of object |
| /// being destroyed. |
| uintptr_t *BaseOrMemberDestructions; |
| unsigned NumBaseOrMemberDestructions; |
| |
| CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L, |
| DeclarationName N, QualType T, |
| bool isInline, bool isImplicitlyDeclared) |
| : CXXMethodDecl(CXXDestructor, RD, L, N, T, false, isInline), |
| ImplicitlyDefined(false), |
| BaseOrMemberDestructions(0), NumBaseOrMemberDestructions(0) { |
| setImplicit(isImplicitlyDeclared); |
| } |
| virtual void Destroy(ASTContext& C); |
| |
| public: |
| static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, |
| SourceLocation L, DeclarationName N, |
| QualType T, bool isInline, |
| bool isImplicitlyDeclared); |
| |
| /// isImplicitlyDefined - Whether this destructor was implicitly |
| /// defined. If false, then this destructor was defined by the |
| /// user. This operation can only be invoked if the destructor has |
| /// already been defined. |
| bool isImplicitlyDefined() const { |
| assert(isThisDeclarationADefinition() && |
| "Can only get the implicit-definition flag once the destructor has been defined"); |
| return ImplicitlyDefined; |
| } |
| |
| /// setImplicitlyDefined - Set whether this destructor was |
| /// implicitly defined or not. |
| void setImplicitlyDefined(bool ID) { |
| assert(isThisDeclarationADefinition() && |
| "Can only set the implicit-definition flag once the destructor has been defined"); |
| ImplicitlyDefined = ID; |
| } |
| |
| /// destr_iterator - Iterates through the member/base destruction list. |
| |
| /// destr_const_iterator - Iterates through the member/base destruction list. |
| typedef uintptr_t const destr_const_iterator; |
| |
| /// destr_begin() - Retrieve an iterator to the first destructed member/base. |
| uintptr_t* destr_begin() { |
| return BaseOrMemberDestructions; |
| } |
| /// destr_begin() - Retrieve an iterator to the first destructed member/base. |
| uintptr_t* destr_begin() const { |
| return BaseOrMemberDestructions; |
| } |
| |
| /// destr_end() - Retrieve an iterator past the last destructed member/base. |
| uintptr_t* destr_end() { |
| return BaseOrMemberDestructions + NumBaseOrMemberDestructions; |
| } |
| /// destr_end() - Retrieve an iterator past the last destructed member/base. |
| uintptr_t* destr_end() const { |
| return BaseOrMemberDestructions + NumBaseOrMemberDestructions; |
| } |
| |
| /// getNumBaseOrMemberDestructions - Number of base and non-static members |
| /// to destroy. |
| unsigned getNumBaseOrMemberDestructions() const { |
| return NumBaseOrMemberDestructions; |
| } |
| |
| /// getBaseOrMember - get the generic 'member' representing either the field |
| /// or a base class. |
| uintptr_t* getBaseOrMemberToDestroy() const { |
| return BaseOrMemberDestructions; |
| } |
| |
| /// isVbaseToDestroy - returns true, if object is virtual base. |
| bool isVbaseToDestroy(uintptr_t Vbase) const { |
| return (Vbase & VBASE) != 0; |
| } |
| /// isDirectNonVBaseToDestroy - returns true, if object is direct non-virtual |
| /// base. |
| bool isDirectNonVBaseToDestroy(uintptr_t DrctNonVbase) const { |
| return (DrctNonVbase & DRCTNONVBASE) != 0; |
| } |
| /// isAnyBaseToDestroy - returns true, if object is any base (virtual or |
| /// direct non-virtual) |
| bool isAnyBaseToDestroy(uintptr_t AnyBase) const { |
| return (AnyBase & ANYBASE) != 0; |
| } |
| /// isMemberToDestroy - returns true if object is a non-static data member. |
| bool isMemberToDestroy(uintptr_t Member) const { |
| return (Member & ANYBASE) == 0; |
| } |
| /// getAnyBaseClassToDestroy - Get the type for the given base class object. |
| Type *getAnyBaseClassToDestroy(uintptr_t Base) const { |
| if (isAnyBaseToDestroy(Base)) |
| return reinterpret_cast<Type*>(Base & ~0x03); |
| return 0; |
| } |
| /// getMemberToDestroy - Get the member for the given object. |
| FieldDecl *getMemberToDestroy(uintptr_t Member) const { |
| if (isMemberToDestroy(Member)) |
| return reinterpret_cast<FieldDecl *>(Member); |
| return 0; |
| } |
| /// getVbaseClassToDestroy - Get the virtual base. |
| Type *getVbaseClassToDestroy(uintptr_t Vbase) const { |
| if (isVbaseToDestroy(Vbase)) |
| return reinterpret_cast<Type*>(Vbase & ~0x01); |
| return 0; |
| } |
| /// getDirectNonVBaseClassToDestroy - Get the virtual base. |
| Type *getDirectNonVBaseClassToDestroy(uintptr_t Base) const { |
| if (isDirectNonVBaseToDestroy(Base)) |
| return reinterpret_cast<Type*>(Base & ~0x02); |
| return 0; |
| } |
| |
| /// computeBaseOrMembersToDestroy - Compute information in current |
| /// destructor decl's AST of bases and non-static data members which will be |
| /// implicitly destroyed. We are storing the destruction in the order that |
| /// they should occur (which is the reverse of construction order). |
| void computeBaseOrMembersToDestroy(ASTContext &C); |
| |
| // Implement isa/cast/dyncast/etc. |
| static bool classof(const Decl *D) { |
| return D->getKind() == CXXDestructor; |
| } |
| static bool classof(const CXXDestructorDecl *D) { return true; } |
| }; |
| |
| /// CXXConversionDecl - Represents a C++ conversion function within a |
| /// class. For example: |
| /// |
| /// @code |
| /// class X { |
| /// public: |
| /// operator bool(); |
| /// }; |
| /// @endcode |
| class CXXConversionDecl : public CXXMethodDecl { |
| /// Explicit - Whether this conversion function is marked |
| /// "explicit", meaning that it can only be applied when the user |
| /// explicitly wrote a cast. This is a C++0x feature. |
| bool Explicit : 1; |
| |
| CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L, |
| DeclarationName N, QualType T, |
| bool isInline, bool isExplicit) |
| : CXXMethodDecl(CXXConversion, RD, L, N, T, false, isInline), |
| Explicit(isExplicit) { } |
| |
| public: |
| static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, |
| SourceLocation L, DeclarationName N, |
| QualType T, bool isInline, |
| bool isExplicit); |
| |
| /// isExplicit - Whether this is an explicit conversion operator |
| /// (C++0x only). Explicit conversion operators are only considered |
| /// when the user has explicitly written a cast. |
| bool isExplicit() const { return Explicit; } |
| |
| /// getConversionType - Returns the type that this conversion |
| /// function is converting to. |
| QualType getConversionType() const { |
| return getType()->getAsFunctionType()->getResultType(); |
| } |
| |
| // Implement isa/cast/dyncast/etc. |
| static bool classof(const Decl *D) { |
| return D->getKind() == CXXConversion; |
| } |
| static bool classof(const CXXConversionDecl *D) { return true; } |
| }; |
| |
| /// LinkageSpecDecl - This represents a linkage specification. For example: |
| /// extern "C" void foo(); |
| /// |
| class LinkageSpecDecl : public Decl, public DeclContext { |
| public: |
| /// LanguageIDs - Used to represent the language in a linkage |
| /// specification. The values are part of the serialization abi for |
| /// ASTs and cannot be changed without altering that abi. To help |
| /// ensure a stable abi for this, we choose the DW_LANG_ encodings |
| /// from the dwarf standard. |
| enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002, |
| lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 }; |
| private: |
| /// Language - The language for this linkage specification. |
| LanguageIDs Language; |
| |
| /// HadBraces - Whether this linkage specification had curly braces or not. |
| bool HadBraces : 1; |
| |
| LinkageSpecDecl(DeclContext *DC, SourceLocation L, LanguageIDs lang, |
| bool Braces) |
| : Decl(LinkageSpec, DC, L), |
| DeclContext(LinkageSpec), Language(lang), HadBraces(Braces) { } |
| |
| public: |
| static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC, |
| SourceLocation L, LanguageIDs Lang, |
| bool Braces); |
| |
| LanguageIDs getLanguage() const { return Language; } |
| |
| /// hasBraces - Determines whether this linkage specification had |
| /// braces in its syntactic form. |
| bool hasBraces() const { return HadBraces; } |
| |
| static bool classof(const Decl *D) { |
| return D->getKind() == LinkageSpec; |
| } |
| static bool classof(const LinkageSpecDecl *D) { return true; } |
| static DeclContext *castToDeclContext(const LinkageSpecDecl *D) { |
| return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D)); |
| } |
| static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) { |
| return static_cast<LinkageSpecDecl *>(const_cast<DeclContext*>(DC)); |
| } |
| }; |
| |
| /// UsingDirectiveDecl - Represents C++ using-directive. For example: |
| /// |
| /// using namespace std; |
| /// |
| // NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide |
| // artificial name, for all using-directives in order to store |
| // them in DeclContext effectively. |
| class UsingDirectiveDecl : public NamedDecl { |
| |
| /// SourceLocation - Location of 'namespace' token. |
| SourceLocation NamespaceLoc; |
| |
| /// \brief The source range that covers the nested-name-specifier |
| /// preceding the namespace name. |
| SourceRange QualifierRange; |
| |
| /// \brief The nested-name-specifier that precedes the namespace |
| /// name, if any. |
| NestedNameSpecifier *Qualifier; |
| |
| /// IdentLoc - Location of nominated namespace-name identifier. |
| // FIXME: We don't store location of scope specifier. |
| SourceLocation IdentLoc; |
| |
| /// NominatedNamespace - Namespace nominated by using-directive. |
| NamespaceDecl *NominatedNamespace; |
| |
| /// Enclosing context containing both using-directive and nomintated |
| /// namespace. |
| DeclContext *CommonAncestor; |
| |
| /// getUsingDirectiveName - Returns special DeclarationName used by |
| /// using-directives. This is only used by DeclContext for storing |
| /// UsingDirectiveDecls in its lookup structure. |
| static DeclarationName getName() { |
| return DeclarationName::getUsingDirectiveName(); |
| } |
| |
| UsingDirectiveDecl(DeclContext *DC, SourceLocation L, |
| SourceLocation NamespcLoc, |
| SourceRange QualifierRange, |
| NestedNameSpecifier *Qualifier, |
| SourceLocation IdentLoc, |
| NamespaceDecl *Nominated, |
| DeclContext *CommonAncestor) |
| : NamedDecl(Decl::UsingDirective, DC, L, getName()), |
| NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange), |
| Qualifier(Qualifier), IdentLoc(IdentLoc), |
| NominatedNamespace(Nominated? Nominated->getOriginalNamespace() : 0), |
| CommonAncestor(CommonAncestor) { |
| } |
| |
| public: |
| /// \brief Retrieve the source range of the nested-name-specifier |
| /// that qualifiers the namespace name. |
| SourceRange getQualifierRange() const { return QualifierRange; } |
| |
| /// \brief Retrieve the nested-name-specifier that qualifies the |
| /// name of the namespace. |
| NestedNameSpecifier *getQualifier() const { return Qualifier; } |
| |
| /// getNominatedNamespace - Returns namespace nominated by using-directive. |
| NamespaceDecl *getNominatedNamespace() { return NominatedNamespace; } |
| |
| const NamespaceDecl *getNominatedNamespace() const { |
| return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace(); |
| } |
| |
| /// getCommonAncestor - returns common ancestor context of using-directive, |
| /// and nominated by it namespace. |
| DeclContext *getCommonAncestor() { return CommonAncestor; } |
| const DeclContext *getCommonAncestor() const { return CommonAncestor; } |
| |
| /// getNamespaceKeyLocation - Returns location of namespace keyword. |
| SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; } |
| |
| /// getIdentLocation - Returns location of identifier. |
| SourceLocation getIdentLocation() const { return IdentLoc; } |
| |
| static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC, |
| SourceLocation L, |
| SourceLocation NamespaceLoc, |
| SourceRange QualifierRange, |
| NestedNameSpecifier *Qualifier, |
| SourceLocation IdentLoc, |
| NamespaceDecl *Nominated, |
| DeclContext *CommonAncestor); |
| |
| static bool classof(const Decl *D) { |
| return D->getKind() == Decl::UsingDirective; |
| } |
| static bool classof(const UsingDirectiveDecl *D) { return true; } |
| |
| // Friend for getUsingDirectiveName. |
| friend class DeclContext; |
| }; |
| |
| /// NamespaceAliasDecl - Represents a C++ namespace alias. For example: |
| /// |
| /// @code |
| /// namespace Foo = Bar; |
| /// @endcode |
| class NamespaceAliasDecl : public NamedDecl { |
| SourceLocation AliasLoc; |
| |
| /// \brief The source range that covers the nested-name-specifier |
| /// preceding the namespace name. |
| SourceRange QualifierRange; |
| |
| /// \brief The nested-name-specifier that precedes the namespace |
| /// name, if any. |
| NestedNameSpecifier *Qualifier; |
| |
| /// IdentLoc - Location of namespace identifier. |
| SourceLocation IdentLoc; |
| |
| /// Namespace - The Decl that this alias points to. Can either be a |
| /// NamespaceDecl or a NamespaceAliasDecl. |
| NamedDecl *Namespace; |
| |
| NamespaceAliasDecl(DeclContext *DC, SourceLocation L, |
| SourceLocation AliasLoc, IdentifierInfo *Alias, |
| SourceRange QualifierRange, |
| NestedNameSpecifier *Qualifier, |
| SourceLocation IdentLoc, NamedDecl *Namespace) |
| : NamedDecl(Decl::NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc), |
| QualifierRange(QualifierRange), Qualifier(Qualifier), |
| IdentLoc(IdentLoc), Namespace(Namespace) { } |
| |
| public: |
| /// \brief Retrieve the source range of the nested-name-specifier |
| /// that qualifiers the namespace name. |
| SourceRange getQualifierRange() const { return QualifierRange; } |
| |
| /// \brief Retrieve the nested-name-specifier that qualifies the |
| /// name of the namespace. |
| NestedNameSpecifier *getQualifier() const { return Qualifier; } |
| |
| NamespaceDecl *getNamespace() { |
| if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace)) |
| return AD->getNamespace(); |
| |
| return cast<NamespaceDecl>(Namespace); |
| } |
| |
| const NamespaceDecl *getNamespace() const { |
| return const_cast<NamespaceAliasDecl*>(this)->getNamespace(); |
| } |
| |
| /// \brief Retrieve the namespace that this alias refers to, which |
| /// may either be a NamespaceDecl or a NamespaceAliasDecl. |
| NamedDecl *getAliasedNamespace() const { return Namespace; } |
| |
| static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC, |
| SourceLocation L, SourceLocation AliasLoc, |
| IdentifierInfo *Alias, |
| SourceRange QualifierRange, |
| NestedNameSpecifier *Qualifier, |
| SourceLocation IdentLoc, |
| NamedDecl *Namespace); |
| |
| static bool classof(const Decl *D) { |
| return D->getKind() == Decl::NamespaceAlias; |
| } |
| static bool classof(const NamespaceAliasDecl *D) { return true; } |
| }; |
| |
| /// UsingDecl - Represents a C++ using-declaration. For example: |
| /// using someNameSpace::someIdentifier; |
| class UsingDecl : public NamedDecl { |
| |
| /// \brief The source range that covers the nested-name-specifier |
| /// preceding the declaration name. |
| SourceRange NestedNameRange; |
| /// \brief The source location of the target declaration name. |
| SourceLocation TargetNameLocation; |
| /// \brief The source location of the "using" location itself. |
| SourceLocation UsingLocation; |
| /// \brief Target declaration. |
| NamedDecl* TargetDecl; |
| /// \brief Target declaration. |
| NestedNameSpecifier* TargetNestedNameDecl; |
| |
| // Had 'typename' keyword. |
| bool IsTypeName; |
| |
| UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR, |
| SourceLocation TargetNL, SourceLocation UL, NamedDecl* Target, |
| NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) |
| : NamedDecl(Decl::Using, DC, L, Target->getDeclName()), |
| NestedNameRange(NNR), TargetNameLocation(TargetNL), |
| UsingLocation(UL), TargetDecl(Target), |
| TargetNestedNameDecl(TargetNNS), IsTypeName(IsTypeNameArg) { |
| this->IdentifierNamespace = TargetDecl->getIdentifierNamespace(); |
| } |
| |
| public: |
| /// \brief Returns the source range that covers the nested-name-specifier |
| /// preceding the namespace name. |
| SourceRange getNestedNameRange() { return NestedNameRange; } |
| |
| /// \brief Returns the source location of the target declaration name. |
| SourceLocation getTargetNameLocation() { return TargetNameLocation; } |
| |
| /// \brief Returns the source location of the "using" location itself. |
| SourceLocation getUsingLocation() { return UsingLocation; } |
| |
| /// \brief getTargetDecl - Returns target specified by using-decl. |
| NamedDecl *getTargetDecl() { return TargetDecl; } |
| const NamedDecl *getTargetDecl() const { return TargetDecl; } |
| |
| /// \brief Get target nested name declaration. |
| NestedNameSpecifier* getTargetNestedNameDecl() { |
| return TargetNestedNameDecl; |
| } |
| |
| /// isTypeName - Return true if using decl had 'typename'. |
| bool isTypeName() const { return IsTypeName; } |
| |
| static UsingDecl *Create(ASTContext &C, DeclContext *DC, |
| SourceLocation L, SourceRange NNR, SourceLocation TargetNL, |
| SourceLocation UL, NamedDecl* Target, |
| NestedNameSpecifier* TargetNNS, bool IsTypeNameArg); |
| |
| static bool classof(const Decl *D) { |
| return D->getKind() == Decl::Using; |
| } |
| static bool classof(const UsingDecl *D) { return true; } |
| }; |
| |
| /// StaticAssertDecl - Represents a C++0x static_assert declaration. |
| class StaticAssertDecl : public Decl { |
| Expr *AssertExpr; |
| StringLiteral *Message; |
| |
| StaticAssertDecl(DeclContext *DC, SourceLocation L, |
| Expr *assertexpr, StringLiteral *message) |
| : Decl(StaticAssert, DC, L), AssertExpr(assertexpr), Message(message) { } |
| |
| public: |
| static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC, |
| SourceLocation L, Expr *AssertExpr, |
| StringLiteral *Message); |
| |
| Expr *getAssertExpr() { return AssertExpr; } |
| const Expr *getAssertExpr() const { return AssertExpr; } |
| |
| StringLiteral *getMessage() { return Message; } |
| const StringLiteral *getMessage() const { return Message; } |
| |
| virtual ~StaticAssertDecl(); |
| virtual void Destroy(ASTContext& C); |
| |
| static bool classof(const Decl *D) { |
| return D->getKind() == Decl::StaticAssert; |
| } |
| static bool classof(StaticAssertDecl *D) { return true; } |
| }; |
| |
| /// Insertion operator for diagnostics. This allows sending AccessSpecifier's |
| /// into a diagnostic with <<. |
| const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, |
| AccessSpecifier AS); |
| |
| } // end namespace clang |
| |
| #endif |