diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h')
-rw-r--r-- | contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h | 668 |
1 files changed, 473 insertions, 195 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h index 7e60773..7f3ec4c 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h @@ -16,10 +16,14 @@ #define LLVM_CLANG_AST_DECLCXX_H #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/Decl.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/UnresolvedSet.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/Compiler.h" namespace clang { @@ -36,7 +40,8 @@ class CXXMemberLookupCriteria; class CXXFinalOverriderMap; class CXXIndirectPrimaryBaseSet; class FriendDecl; - +class LambdaExpr; + /// \brief Represents any kind of function declaration, whether it is a /// concrete function or a function template. class AnyFunctionDecl { @@ -104,6 +109,7 @@ namespace clang { /// Also note that this class has nothing to do with so-called /// "access declarations" (C++98 11.3 [class.access.dcl]). class AccessSpecDecl : public Decl { + virtual void anchor(); /// ColonLoc - The location of the ':'. SourceLocation ColonLoc; @@ -125,7 +131,7 @@ public: /// setColonLoc - Sets the location of the colon. void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getAccessSpecifierLoc(), getColonLoc()); } @@ -134,9 +140,7 @@ public: SourceLocation ColonLoc) { return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc); } - static AccessSpecDecl *Create(ASTContext &C, EmptyShell Empty) { - return new (C) AccessSpecDecl(Empty); - } + static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -170,7 +174,7 @@ class CXXBaseSpecifier { /// \brief The source location of the ellipsis, if this is a pack /// expansion. SourceLocation EllipsisLoc; - + /// Virtual - Whether this is a virtual base class or not. bool Virtual : 1; @@ -200,12 +204,14 @@ public: CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, TypeSourceInfo *TInfo, SourceLocation EllipsisLoc) - : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC), + : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC), Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { } /// getSourceRange - Retrieves the source range that contains the /// entire base specifier. - SourceRange getSourceRange() const { return Range; } + SourceRange getSourceRange() const LLVM_READONLY { return Range; } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } /// isVirtual - Determines whether the base class is a virtual base /// class (or not). @@ -214,7 +220,7 @@ public: /// \brief Determine whether this base class is a base of a class declared /// with the 'class' keyword (vs. one declared with the 'struct' keyword). bool isBaseOfClass() const { return BaseOfClass; } - + /// \brief Determine whether this base specifier is a pack expansion. bool isPackExpansion() const { return EllipsisLoc.isValid(); } @@ -319,7 +325,8 @@ class CXXRecordDecl : public RecordDecl { /// * has no non-static data members of type non-standard-layout class (or /// array of such types) or reference, /// * has no virtual functions (10.3) and no virtual base classes (10.1), - /// * has the same access control (Clause 11) for all non-static data members + /// * has the same access control (Clause 11) for all non-static data + /// members /// * has no non-standard-layout base classes, /// * either has no non-static data members in the most derived class and at /// most one base class with non-static data members, or has no base @@ -346,7 +353,10 @@ class CXXRecordDecl : public RecordDecl { /// \brief True if this class (or any subobject) has mutable fields. bool HasMutableFields : 1; - + + /// \brief True if there no non-field members declared by the user. + bool HasOnlyCMembers : 1; + /// HasTrivialDefaultConstructor - True when, if this class has a default /// constructor, this default constructor is trivial. /// @@ -364,10 +374,34 @@ class CXXRecordDecl : public RecordDecl { bool HasTrivialDefaultConstructor : 1; /// HasConstexprNonCopyMoveConstructor - True when this class has at least - /// one constexpr constructor which is neither the copy nor move - /// constructor. + /// one user-declared constexpr constructor which is neither the copy nor + /// move constructor. bool HasConstexprNonCopyMoveConstructor : 1; + /// DefaultedDefaultConstructorIsConstexpr - True if a defaulted default + /// constructor for this class would be constexpr. + bool DefaultedDefaultConstructorIsConstexpr : 1; + + /// DefaultedCopyConstructorIsConstexpr - True if a defaulted copy + /// constructor for this class would be constexpr. + bool DefaultedCopyConstructorIsConstexpr : 1; + + /// DefaultedMoveConstructorIsConstexpr - True if a defaulted move + /// constructor for this class would be constexpr. + bool DefaultedMoveConstructorIsConstexpr : 1; + + /// HasConstexprDefaultConstructor - True if this class has a constexpr + /// default constructor (either user-declared or implicitly declared). + bool HasConstexprDefaultConstructor : 1; + + /// HasConstexprCopyConstructor - True if this class has a constexpr copy + /// constructor (either user-declared or implicitly declared). + bool HasConstexprCopyConstructor : 1; + + /// HasConstexprMoveConstructor - True if this class has a constexpr move + /// constructor (either user-declared or implicitly declared). + bool HasConstexprMoveConstructor : 1; + /// HasTrivialCopyConstructor - True when this class has a trivial copy /// constructor. /// @@ -438,8 +472,13 @@ class CXXRecordDecl : public RecordDecl { /// type (or array thereof), each such class has a trivial destructor. bool HasTrivialDestructor : 1; + /// HasIrrelevantDestructor - True when this class has a destructor with no + /// semantic effect. + bool HasIrrelevantDestructor : 1; + /// HasNonLiteralTypeFieldsOrBases - True when this class contains at least - /// one non-static data member or base class of non literal type. + /// one non-static data member or base class of non-literal or volatile + /// type. bool HasNonLiteralTypeFieldsOrBases : 1; /// ComputedVisibleConversions - True when visible conversion functions are @@ -458,13 +497,13 @@ class CXXRecordDecl : public RecordDecl { /// \brief Whether we have already declared the move constructor. bool DeclaredMoveConstructor : 1; - + /// \brief Whether we have already declared the copy-assignment operator. bool DeclaredCopyAssignment : 1; /// \brief Whether we have already declared the move-assignment operator. bool DeclaredMoveAssignment : 1; - + /// \brief Whether we have already declared a destructor within the class. bool DeclaredDestructor : 1; @@ -476,9 +515,12 @@ class CXXRecordDecl : public RecordDecl { /// declared but would have been deleted. bool FailedImplicitMoveAssignment : 1; + /// \brief Whether this class describes a C++ lambda. + bool IsLambda : 1; + /// NumBases - The number of base class specifiers in Bases. unsigned NumBases; - + /// NumVBases - The number of virtual base class specifiers in VBases. unsigned NumVBases; @@ -510,17 +552,59 @@ class CXXRecordDecl : public RecordDecl { /// in reverse order. FriendDecl *FirstFriend; - /// \brief Retrieve the set of direct base classes. + /// \brief Retrieve the set of direct base classes. CXXBaseSpecifier *getBases() const { return Bases.get(Definition->getASTContext().getExternalSource()); } - /// \brief Retrieve the set of virtual base classes. + /// \brief Retrieve the set of virtual base classes. CXXBaseSpecifier *getVBases() const { return VBases.get(Definition->getASTContext().getExternalSource()); } } *DefinitionData; + /// \brief Describes a C++ closure type (generated by a lambda expression). + struct LambdaDefinitionData : public DefinitionData { + typedef LambdaExpr::Capture Capture; + + LambdaDefinitionData(CXXRecordDecl *D, bool Dependent) + : DefinitionData(D), Dependent(Dependent), NumCaptures(0), + NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0) + { + IsLambda = true; + } + + /// \brief Whether this lambda is known to be dependent, even if its + /// context isn't dependent. + /// + /// A lambda with a non-dependent context can be dependent if it occurs + /// within the default argument of a function template, because the + /// lambda will have been created with the enclosing context as its + /// declaration context, rather than function. This is an unfortunate + /// artifact of having to parse the default arguments before + unsigned Dependent : 1; + + /// \brief The number of captures in this lambda. + unsigned NumCaptures : 16; + + /// \brief The number of explicit captures in this lambda. + unsigned NumExplicitCaptures : 15; + + /// \brief The number used to indicate this lambda expression for name + /// mangling in the Itanium C++ ABI. + unsigned ManglingNumber; + + /// \brief The declaration that provides context for this lambda, if the + /// actual DeclContext does not suffice. This is used for lambdas that + /// occur within default arguments of function parameters within the class + /// or within a data member initializer. + Decl *ContextDecl; + + /// \brief The list of captures, both explicit and implicit, for this + /// lambda. + Capture *Captures; + }; + struct DefinitionData &data() { assert(DefinitionData && "queried property of class with no definition"); return *DefinitionData; @@ -530,6 +614,13 @@ class CXXRecordDecl : public RecordDecl { assert(DefinitionData && "queried property of class with no definition"); return *DefinitionData; } + + struct LambdaDefinitionData &getLambdaData() const { + assert(DefinitionData && "queried property of lambda with no definition"); + assert(DefinitionData->IsLambda && + "queried lambda property of non-lambda class"); + return static_cast<LambdaDefinitionData &>(*DefinitionData); + } /// \brief The template or declaration that this declaration /// describes or was instantiated from, respectively. @@ -538,23 +629,26 @@ class CXXRecordDecl : public RecordDecl { /// 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 - /// MemberSpecializationInfo referring to the member class that was + /// MemberSpecializationInfo referring to the member class that was /// instantiated or specialized. llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*> TemplateOrInstantiation; friend class DeclContext; - + friend class LambdaExpr; + /// \brief Notify the class that member has been added. /// - /// This routine helps maintain information about the class based on which + /// This routine helps maintain information about the class based on which /// members have been added. It will be invoked by DeclContext::addDecl() /// whenever a member is added to this record. void addedMember(Decl *D); void markedVirtualFunctionPure(); friend void FunctionDecl::setPure(bool); - + + friend class ASTNodeImporter; + protected: CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -585,12 +679,19 @@ public: virtual const CXXRecordDecl *getCanonicalDecl() const { return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl()); } - - const CXXRecordDecl *getPreviousDeclaration() const { - return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDeclaration()); + + const CXXRecordDecl *getPreviousDecl() const { + return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDecl()); } - CXXRecordDecl *getPreviousDeclaration() { - return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDeclaration()); + CXXRecordDecl *getPreviousDecl() { + return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDecl()); + } + + const CXXRecordDecl *getMostRecentDecl() const { + return cast_or_null<CXXRecordDecl>(RecordDecl::getMostRecentDecl()); + } + CXXRecordDecl *getMostRecentDecl() { + return cast_or_null<CXXRecordDecl>(RecordDecl::getMostRecentDecl()); } CXXRecordDecl *getDefinition() const { @@ -604,7 +705,9 @@ public: SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0, bool DelayTypeCreation = false); - static CXXRecordDecl *Create(const ASTContext &C, EmptyShell Empty); + static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC, + SourceLocation Loc, bool DependentLambda); + static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); bool isDynamicClass() const { return data().Polymorphic || data().NumVBases != 0; @@ -704,7 +807,7 @@ public: /// /// This value is used for lazy creation of default constructors. bool needsImplicitDefaultConstructor() const { - return !data().UserDeclaredConstructor && + return !data().UserDeclaredConstructor && !data().DeclaredDefaultConstructor; } @@ -722,11 +825,11 @@ public: CXXConstructorDecl *getCopyConstructor(unsigned TypeQuals) const; /// getMoveConstructor - Returns the move constructor for this class - CXXConstructorDecl *getMoveConstructor() const; + CXXConstructorDecl *getMoveConstructor() const; /// \brief Retrieve the copy-assignment operator for this class, if available. /// - /// This routine attempts to find the copy-assignment operator for this + /// This routine attempts to find the copy-assignment operator for this /// class, using a simplistic form of overload resolution. /// /// \param ArgIsConst Whether the argument to the copy-assignment operator @@ -739,7 +842,7 @@ public: /// getMoveAssignmentOperator - Returns the move assignment operator for this /// class CXXMethodDecl *getMoveAssignmentOperator() const; - + /// hasUserDeclaredConstructor - Whether this class has any /// user-declared constructors. When true, a default constructor /// will not be implicitly declared. @@ -760,7 +863,7 @@ public: return data().UserDeclaredCopyConstructor; } - /// \brief Determine whether this class has had its copy constructor + /// \brief Determine whether this class has had its copy constructor /// declared, either via the user or via an implicit declaration. /// /// This value is used for lazy creation of copy constructors. @@ -822,7 +925,7 @@ public: return data().UserDeclaredCopyAssignment; } - /// \brief Determine whether this class has had its copy assignment operator + /// \brief Determine whether this class has had its copy assignment operator /// declared, either via the user or via an implicit declaration. /// /// This value is used for lazy creation of copy assignment operators. @@ -882,6 +985,29 @@ public: /// This value is used for lazy creation of destructors. bool hasDeclaredDestructor() const { return data().DeclaredDestructor; } + /// \brief Determine whether this class describes a lambda function object. + bool isLambda() const { return hasDefinition() && data().IsLambda; } + + /// \brief For a closure type, retrieve the mapping from captured + /// variables and this to the non-static data members that store the + /// values or references of the captures. + /// + /// \param Captures Will be populated with the mapping from captured + /// variables to the corresponding fields. + /// + /// \param ThisCapture Will be set to the field declaration for the + /// 'this' capture. + void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures, + FieldDecl *&ThisCapture) const; + + typedef const LambdaExpr::Capture* capture_const_iterator; + capture_const_iterator captures_begin() const { + return isLambda() ? getLambdaData().Captures : NULL; + } + capture_const_iterator captures_end() const { + return isLambda() ? captures_begin() + getLambdaData().NumCaptures : NULL; + } + /// getConversions - Retrieve the overload set containing all of the /// conversion functions in this class. UnresolvedSetImpl *getConversionFunctions() { @@ -920,6 +1046,10 @@ public: /// user-defined destructor. bool isPOD() const { return data().PlainOldData; } + /// \brief True if this class is C-like, without C++-specific features, e.g. + /// it contains only public fields, no bases, tag kind is not 'class', etc. + bool isCLike() const; + /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which /// means it has a virtual function, virtual base, data member (other than /// 0-width bit-field) or inherits from a non-empty class. Does NOT include @@ -941,20 +1071,63 @@ public: /// \brief Whether this class, or any of its class subobjects, contains a /// mutable field. bool hasMutableFields() const { return data().HasMutableFields; } - - // hasTrivialDefaultConstructor - Whether this class has a trivial default - // constructor - // (C++0x [class.ctor]p5) + + /// hasTrivialDefaultConstructor - Whether this class has a trivial default + /// constructor (C++11 [class.ctor]p5). bool hasTrivialDefaultConstructor() const { return data().HasTrivialDefaultConstructor && (!data().UserDeclaredConstructor || data().DeclaredDefaultConstructor); } - // hasConstexprNonCopyMoveConstructor - Whether this class has at least one - // constexpr constructor other than the copy or move constructors. + /// hasConstexprNonCopyMoveConstructor - Whether this class has at least one + /// constexpr constructor other than the copy or move constructors. bool hasConstexprNonCopyMoveConstructor() const { - return data().HasConstexprNonCopyMoveConstructor; + return data().HasConstexprNonCopyMoveConstructor || + (!hasUserDeclaredConstructor() && + defaultedDefaultConstructorIsConstexpr()); + } + + /// defaultedDefaultConstructorIsConstexpr - Whether a defaulted default + /// constructor for this class would be constexpr. + bool defaultedDefaultConstructorIsConstexpr() const { + return data().DefaultedDefaultConstructorIsConstexpr; + } + + /// defaultedCopyConstructorIsConstexpr - Whether a defaulted copy + /// constructor for this class would be constexpr. + bool defaultedCopyConstructorIsConstexpr() const { + return data().DefaultedCopyConstructorIsConstexpr; + } + + /// defaultedMoveConstructorIsConstexpr - Whether a defaulted move + /// constructor for this class would be constexpr. + bool defaultedMoveConstructorIsConstexpr() const { + return data().DefaultedMoveConstructorIsConstexpr; + } + + /// hasConstexprDefaultConstructor - Whether this class has a constexpr + /// default constructor. + bool hasConstexprDefaultConstructor() const { + return data().HasConstexprDefaultConstructor || + (!data().UserDeclaredConstructor && + data().DefaultedDefaultConstructorIsConstexpr && isLiteral()); + } + + /// hasConstexprCopyConstructor - Whether this class has a constexpr copy + /// constructor. + bool hasConstexprCopyConstructor() const { + return data().HasConstexprCopyConstructor || + (!data().DeclaredCopyConstructor && + data().DefaultedCopyConstructorIsConstexpr && isLiteral()); + } + + /// hasConstexprMoveConstructor - Whether this class has a constexpr move + /// constructor. + bool hasConstexprMoveConstructor() const { + return data().HasConstexprMoveConstructor || + (needsImplicitMoveConstructor() && + data().DefaultedMoveConstructorIsConstexpr && isLiteral()); } // hasTrivialCopyConstructor - Whether this class has a trivial copy @@ -985,8 +1158,15 @@ public: // (C++ [class.dtor]p3) bool hasTrivialDestructor() const { return data().HasTrivialDestructor; } - // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal type - // non-static data member or base class. + // hasIrrelevantDestructor - Whether this class has a destructor which has no + // semantic effect. Any such destructor will be trivial, public, defaulted + // and not deleted, and will call only irrelevant destructors. + bool hasIrrelevantDestructor() const { + return data().HasIrrelevantDestructor; + } + + // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal or + // volatile type non-static data member or base class. bool hasNonLiteralTypeFieldsOrBases() const { return data().HasNonLiteralTypeFieldsOrBases; } @@ -1006,20 +1186,23 @@ public: // isLiteral - Whether this class is a literal type. // - // C++0x [basic.types]p10 + // C++11 [basic.types]p10 // A class type that has all the following properties: - // -- a trivial destructor + // -- it has a trivial destructor // -- every constructor call and full-expression in the // brace-or-equal-intializers for non-static data members (if any) is // a constant expression. // -- it is an aggregate type or has at least one constexpr constructor or // constructor template that is not a copy or move constructor, and - // -- all non-static data members and base classes of literal types + // -- all of its non-static data members and base classes are of literal + // types // - // We resolve DR1361 by ignoring the second bullet. + // We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by + // treating types with trivial default constructors as literal types. bool isLiteral() const { return hasTrivialDestructor() && - (isAggregate() || hasConstexprNonCopyMoveConstructor()) && + (isAggregate() || hasConstexprNonCopyMoveConstructor() || + hasTrivialDefaultConstructor()) && !hasNonLiteralTypeFieldsOrBases(); } @@ -1043,12 +1226,12 @@ public: /// X<int>::A is required, it will be instantiated from the /// declaration returned by getInstantiatedFromMemberClass(). CXXRecordDecl *getInstantiatedFromMemberClass() const; - + /// \brief If this class is an instantiation of a member class of a /// class template specialization, retrieves the member specialization /// information. MemberSpecializationInfo *getMemberSpecializationInfo() const; - + /// \brief Specify that this record is an instantiation of the /// member class RD. void setInstantiationOfMemberClass(CXXRecordDecl *RD, @@ -1077,7 +1260,7 @@ public: /// instantiation of a class template or member class of a class template, /// and how it was instantiated or specialized. TemplateSpecializationKind getTemplateSpecializationKind() const; - + /// \brief Set the kind of specialization or template instantiation this is. void setTemplateSpecializationKind(TemplateSpecializationKind TSK); @@ -1104,7 +1287,7 @@ public: /// /// \returns true if this class is derived from Base, false otherwise. bool isDerivedFrom(const CXXRecordDecl *Base) const; - + /// \brief Determine whether this class is derived from the type \p Base. /// /// This routine only determines whether this class is derived from \p Base, @@ -1119,8 +1302,8 @@ public: /// /// \returns true if this class is derived from Base, false otherwise. /// - /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than - /// tangling input and output in \p Paths + /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than + /// tangling input and output in \p Paths bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const; /// \brief Determine whether this class is virtually derived from @@ -1155,20 +1338,20 @@ public: /// /// The class itself does not count as a base class. This routine /// returns false if the class has non-computable base classes. - /// + /// /// \param AllowShortCircuit if false, forces the callback to be called /// for every base class, even if a dependent or non-matching base was /// found. bool forallBases(ForallBasesCallback *BaseMatches, void *UserData, bool AllowShortCircuit = true) const; - - /// \brief Function type used by lookupInBases() to determine whether a + + /// \brief Function type used by lookupInBases() to determine whether a /// specific base class subobject matches the lookup criteria. /// - /// \param Specifier the base-class specifier that describes the inheritance + /// \param Specifier the base-class specifier that describes the inheritance /// from the base class we are trying to match. /// - /// \param Path the current path, from the most-derived class down to the + /// \param Path the current path, from the most-derived class down to the /// base named by the \p Specifier. /// /// \param UserData a single pointer to user-specified data, provided to @@ -1178,13 +1361,13 @@ public: typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, void *UserData); - + /// \brief Look for entities within the base classes of this C++ class, /// transitively searching all base class subobjects. /// - /// This routine uses the callback function \p BaseMatches to find base + /// This routine uses the callback function \p BaseMatches to find base /// classes meeting some search criteria, walking all base class subobjects - /// and populating the given \p Paths structure with the paths through the + /// and populating the given \p Paths structure with the paths through the /// inheritance hierarchy that resulted in a match. On a successful search, /// the \p Paths structure can be queried to retrieve the matching paths and /// to determine if there were any ambiguities. @@ -1201,7 +1384,7 @@ public: /// subobject that matches the search criteria. bool lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData, CXXBasePaths &Paths) const; - + /// \brief Base-class lookup callback that determines whether the given /// base class specifier refers to a specific class declaration. /// @@ -1223,7 +1406,7 @@ public: /// are searching for. static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, void *BaseRecord); - + /// \brief Base-class lookup callback that determines whether there exists /// a tag with the given name. /// @@ -1241,7 +1424,7 @@ public: /// is an opaque \c DeclarationName pointer. static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, void *Name); - + /// \brief Base-class lookup callback that determines whether there exists /// a member with the given name that can be used in a nested-name-specifier. /// @@ -1277,15 +1460,15 @@ public: /// \brief Indicates that the definition of this class is now complete. virtual void completeDefinition(); - /// \brief Indicates that the definition of this class is now complete, + /// \brief Indicates that the definition of this class is now complete, /// and provides a final overrider map to help determine - /// + /// /// \param FinalOverriders The final overrider map for this class, which can /// be provided as an optimization for abstract-class checking. If NULL, /// final overriders will be computed if they are needed to complete the /// definition. void completeDefinition(CXXFinalOverriderMap *FinalOverriders); - + /// \brief Determine whether this class may end up being abstract, even though /// it is not yet known to be abstract. /// @@ -1294,6 +1477,53 @@ public: /// will need to compute final overriders to determine whether the class is /// actually abstract. bool mayBeAbstract() const; + + /// \brief If this is the closure type of a lambda expression, retrieve the + /// number to be used for name mangling in the Itanium C++ ABI. + /// + /// Zero indicates that this closure type has internal linkage, so the + /// mangling number does not matter, while a non-zero value indicates which + /// lambda expression this is in this particular context. + unsigned getLambdaManglingNumber() const { + assert(isLambda() && "Not a lambda closure type!"); + return getLambdaData().ManglingNumber; + } + + /// \brief Retrieve the declaration that provides additional context for a + /// lambda, when the normal declaration context is not specific enough. + /// + /// Certain contexts (default arguments of in-class function parameters and + /// the initializers of data members) have separate name mangling rules for + /// lambdas within the Itanium C++ ABI. For these cases, this routine provides + /// the declaration in which the lambda occurs, e.g., the function parameter + /// or the non-static data member. Otherwise, it returns NULL to imply that + /// the declaration context suffices. + Decl *getLambdaContextDecl() const { + assert(isLambda() && "Not a lambda closure type!"); + return getLambdaData().ContextDecl; + } + + /// \brief Set the mangling number and context declaration for a lambda + /// class. + void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl) { + getLambdaData().ManglingNumber = ManglingNumber; + getLambdaData().ContextDecl = ContextDecl; + } + + /// \brief Determine whether this lambda expression was known to be dependent + /// at the time it was created, even if its context does not appear to be + /// dependent. + /// + /// This flag is a workaround for an issue with parsing, where default + /// arguments are parsed before their enclosing function declarations have + /// been created. This means that any lambda expressions within those + /// default arguments will have as their DeclContext the context enclosing + /// the function declaration, which may be non-dependent even when the + /// function declaration itself is dependent. This flag indicates when we + /// know that the lambda is dependent despite that. + bool isDependentLambda() const { + return isLambda() && getLambdaData().Dependent; + } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { @@ -1313,6 +1543,7 @@ public: /// CXXMethodDecl - Represents a static or instance method of a /// struct/union/class. class CXXMethodDecl : public FunctionDecl { + virtual void anchor(); protected: CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, @@ -1322,9 +1553,9 @@ protected: : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo, (isStatic ? SC_Static : SC_None), SCAsWritten, isInline, isConstexpr) { - if (EndLocation.isValid()) - setRangeEnd(EndLocation); - } + if (EndLocation.isValid()) + setRangeEnd(EndLocation); + } public: static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD, @@ -1337,16 +1568,18 @@ public: bool isConstexpr, SourceLocation EndLocation); + static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); + bool isStatic() const { return getStorageClass() == SC_Static; } bool isInstance() const { return !isStatic(); } bool isVirtual() const { - CXXMethodDecl *CD = + CXXMethodDecl *CD = cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl()); if (CD->isVirtualAsWritten()) return true; - + return (CD->begin_overridden_methods() != CD->end_overridden_methods()); } @@ -1354,14 +1587,14 @@ public: /// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded /// delete or delete[] operator with a particular signature. bool isUsualDeallocationFunction() const; - + /// \brief Determine whether this is a copy-assignment operator, regardless /// of whether it was declared implicitly or explicitly. bool isCopyAssignmentOperator() const; /// \brief Determine whether this is a move assignment operator. bool isMoveAssignmentOperator() const; - + const CXXMethodDecl *getCanonicalDecl() const { return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl()); } @@ -1374,11 +1607,11 @@ public: bool isUserProvided() const { return !(isDeleted() || getCanonicalDecl()->isDefaulted()); } - + /// void addOverriddenMethod(const CXXMethodDecl *MD); - typedef const CXXMethodDecl ** method_iterator; + typedef const CXXMethodDecl *const* method_iterator; method_iterator begin_overridden_methods() const; method_iterator end_overridden_methods() const; @@ -1419,9 +1652,18 @@ public: RefQualifierKind getRefQualifier() const { return getType()->getAs<FunctionProtoType>()->getRefQualifier(); } - + bool hasInlineBody() const; + /// \brief Determine whether this is a lambda closure type's static member + /// function that is used for the result of the lambda's conversion to + /// function pointer (for a lambda with no captures). + /// + /// The function itself, if used, will have a placeholder body that will be + /// supplied by IR generation to either forward to the function call operator + /// or clone the function call operator. + bool isLambdaStaticInvoker() const; + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const CXXMethodDecl *D) { return true; } @@ -1445,31 +1687,34 @@ public: /// }; /// @endcode class CXXCtorInitializer { - /// \brief Either the base class name (stored as a TypeSourceInfo*), an normal - /// field (FieldDecl), anonymous field (IndirectFieldDecl*), or target - /// constructor (CXXConstructorDecl*) being initialized. - llvm::PointerUnion4<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *, - CXXConstructorDecl *> + /// \brief Either the base class name/delegating constructor type (stored as + /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field + /// (IndirectFieldDecl*) being initialized. + llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *> Initializee; - + /// \brief The source location for the field name or, for a base initializer /// pack expansion, the location of the ellipsis. In the case of a delegating /// constructor, it will still include the type's source location as the /// Initializee points to the CXXConstructorDecl (to allow loop detection). SourceLocation MemberOrEllipsisLocation; - + /// \brief The argument used to initialize the base or member, which may /// end up constructing an object (when multiple arguments are involved). - /// If 0, this is a field initializer, and the in-class member initializer + /// If 0, this is a field initializer, and the in-class member initializer /// will be used. Stmt *Init; - + /// LParenLoc - Location of the left paren of the ctor-initializer. SourceLocation LParenLoc; /// RParenLoc - Location of the right paren of the ctor-initializer. SourceLocation RParenLoc; + /// \brief If the initializee is a type, whether that type makes this + /// a delegating initialization. + bool IsDelegating : 1; + /// IsVirtual - If the initializer is a base initializer, this keeps track /// of whether the base is virtual or not. bool IsVirtual : 1; @@ -1483,12 +1728,12 @@ class CXXCtorInitializer { /// original sources, counting from 0; otherwise, if IsWritten is false, /// it stores the number of array index variables stored after this /// object in memory. - unsigned SourceOrderOrNumArrayIndices : 14; + unsigned SourceOrderOrNumArrayIndices : 13; CXXCtorInitializer(ASTContext &Context, FieldDecl *Member, SourceLocation MemberLoc, SourceLocation L, Expr *Init, SourceLocation R, VarDecl **Indices, unsigned NumIndices); - + public: /// CXXCtorInitializer - Creates a new base-class initializer. explicit @@ -1510,25 +1755,27 @@ public: /// CXXCtorInitializer - Creates a new delegating Initializer. explicit - CXXCtorInitializer(ASTContext &Context, SourceLocation D, SourceLocation L, - CXXConstructorDecl *Target, Expr *Init, SourceLocation R); + CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, + SourceLocation L, Expr *Init, SourceLocation R); - /// \brief Creates a new member initializer that optionally contains + /// \brief Creates a new member initializer that optionally contains /// array indices used to describe an elementwise initialization. static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member, SourceLocation MemberLoc, SourceLocation L, Expr *Init, SourceLocation R, VarDecl **Indices, unsigned NumIndices); - + /// isBaseInitializer - Returns true when this initializer is /// initializing a base class. - bool isBaseInitializer() const { return Initializee.is<TypeSourceInfo*>(); } + bool isBaseInitializer() const { + return Initializee.is<TypeSourceInfo*>() && !IsDelegating; + } /// isMemberInitializer - Returns true when this initializer is /// initializing a non-static data member. bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); } - bool isAnyMemberInitializer() const { + bool isAnyMemberInitializer() const { return isMemberInitializer() || isIndirectMemberInitializer(); } @@ -1546,21 +1793,21 @@ public: /// isDelegatingInitializer - Returns true when this initializer is creating /// a delegating constructor. bool isDelegatingInitializer() const { - return Initializee.is<CXXConstructorDecl *>(); + return Initializee.is<TypeSourceInfo*>() && IsDelegating; } /// \brief Determine whether this initializer is a pack expansion. - bool isPackExpansion() const { - return isBaseInitializer() && MemberOrEllipsisLocation.isValid(); + bool isPackExpansion() const { + return isBaseInitializer() && MemberOrEllipsisLocation.isValid(); } - + // \brief For a pack expansion, returns the location of the ellipsis. SourceLocation getEllipsisLoc() const { assert(isPackExpansion() && "Initializer is not a pack expansion"); return MemberOrEllipsisLocation; } - - /// If this is a base class initializer, returns the type of the + + /// If this is a base class initializer, returns the type of the /// base class with location information. Otherwise, returns an NULL /// type location. TypeLoc getBaseClassLoc() const; @@ -1572,56 +1819,47 @@ public: /// Returns whether the base is virtual or not. bool isBaseVirtual() const { assert(isBaseInitializer() && "Must call this on base initializer!"); - + return IsVirtual; } - /// \brief Returns the declarator information for a base class initializer. - TypeSourceInfo *getBaseClassInfo() const { + /// \brief Returns the declarator information for a base class or delegating + /// initializer. + TypeSourceInfo *getTypeSourceInfo() const { return Initializee.dyn_cast<TypeSourceInfo *>(); } - + /// getMember - If this is a member initializer, returns the /// declaration of the non-static data member being /// initialized. Otherwise, returns NULL. FieldDecl *getMember() const { if (isMemberInitializer()) return Initializee.get<FieldDecl*>(); - else - return 0; + return 0; } FieldDecl *getAnyMember() const { if (isMemberInitializer()) return Initializee.get<FieldDecl*>(); - else if (isIndirectMemberInitializer()) + if (isIndirectMemberInitializer()) return Initializee.get<IndirectFieldDecl*>()->getAnonField(); - else - return 0; + return 0; } IndirectFieldDecl *getIndirectMember() const { if (isIndirectMemberInitializer()) return Initializee.get<IndirectFieldDecl*>(); - else - return 0; + return 0; } - CXXConstructorDecl *getTargetConstructor() const { - if (isDelegatingInitializer()) - return Initializee.get<CXXConstructorDecl*>(); - else - return 0; - } - - SourceLocation getMemberLocation() const { + SourceLocation getMemberLocation() const { return MemberOrEllipsisLocation; } - + /// \brief Determine the source location of the initializer. SourceLocation getSourceLocation() const; - + /// \brief Determine the source range covering the entire initializer. - SourceRange getSourceRange() const; + SourceRange getSourceRange() const LLVM_READONLY; /// isWritten - Returns true if this initializer is explicitly written /// in the source code. @@ -1656,7 +1894,7 @@ public: return IsWritten ? 0 : SourceOrderOrNumArrayIndices; } - /// \brief Retrieve a particular array index variable used to + /// \brief Retrieve a particular array index variable used to /// describe an array member initialization. VarDecl *getArrayIndex(unsigned I) { assert(I < getNumArrayIndices() && "Out of bounds member array index"); @@ -1670,7 +1908,12 @@ public: assert(I < getNumArrayIndices() && "Out of bounds member array index"); reinterpret_cast<VarDecl **>(this + 1)[I] = Index; } - + ArrayRef<VarDecl *> getArrayIndexes() { + assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init"); + return ArrayRef<VarDecl *>(reinterpret_cast<VarDecl **>(this + 1), + getNumArrayIndices()); + } + /// \brief Get the initializer. This is 0 if this is an in-class initializer /// for a non-static data member which has not yet been parsed. Expr *getInit() const { @@ -1691,6 +1934,7 @@ public: /// }; /// @endcode class CXXConstructorDecl : public CXXMethodDecl { + virtual void anchor(); /// IsExplicitSpecified - Whether this constructor declaration has the /// 'explicit' keyword specified. bool IsExplicitSpecified : 1; @@ -1712,7 +1956,7 @@ class CXXConstructorDecl : public CXXMethodDecl { CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isExplicitSpecified, bool isInline, + bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared, bool isConstexpr) : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, false, SC_None, isInline, isConstexpr, SourceLocation()), @@ -1722,7 +1966,7 @@ class CXXConstructorDecl : public CXXMethodDecl { } public: - static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty); + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID); static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, @@ -1734,7 +1978,7 @@ public: /// isExplicitSpecified - Whether this constructor declaration has the /// 'explicit' keyword specified. bool isExplicitSpecified() const { return IsExplicitSpecified; } - + /// isExplicit - Whether this constructor was marked "explicit" or not. bool isExplicit() const { return cast<CXXConstructorDecl>(getFirstDeclaration()) @@ -1782,7 +2026,8 @@ public: } typedef std::reverse_iterator<init_iterator> init_reverse_iterator; - typedef std::reverse_iterator<init_const_iterator> init_const_reverse_iterator; + typedef std::reverse_iterator<init_const_iterator> + init_const_reverse_iterator; init_reverse_iterator init_rbegin() { return init_reverse_iterator(init_end()); @@ -1821,11 +2066,7 @@ public: /// getTargetConstructor - When this constructor delegates to /// another, retrieve the target - CXXConstructorDecl *getTargetConstructor() const { - assert(isDelegatingConstructor() && - "A non-delegating constructor has no target"); - return CtorInitializers[0]->getTargetConstructor(); - } + CXXConstructorDecl *getTargetConstructor() const; /// isDefaultConstructor - Whether this constructor is a default /// constructor (C++ [class.ctor]p5), which can be used to @@ -1902,12 +2143,12 @@ public: CXXConstructorDecl *getCanonicalDecl() { return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl()); } - + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const CXXConstructorDecl *D) { return true; } static bool classofKind(Kind K) { return K == CXXConstructor; } - + friend class ASTDeclReader; friend class ASTDeclWriter; }; @@ -1922,6 +2163,7 @@ public: /// }; /// @endcode class CXXDestructorDecl : public CXXMethodDecl { + virtual void anchor(); /// 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 @@ -1931,7 +2173,7 @@ class CXXDestructorDecl : public CXXMethodDecl { bool ImplicitlyDefined : 1; FunctionDecl *OperatorDelete; - + CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, @@ -1943,13 +2185,13 @@ class CXXDestructorDecl : public CXXMethodDecl { } public: - static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty); static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo* TInfo, bool isInline, bool isImplicitlyDeclared); + static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID); /// isImplicitlyDefined - Whether this destructor was implicitly /// defined. If false, then this destructor was defined by the @@ -1957,7 +2199,8 @@ public: /// already been defined. bool isImplicitlyDefined() const { assert(isThisDeclarationADefinition() && - "Can only get the implicit-definition flag once the destructor has been defined"); + "Can only get the implicit-definition flag once the destructor has " + "been defined"); return ImplicitlyDefined; } @@ -1965,7 +2208,8 @@ public: /// implicitly defined or not. void setImplicitlyDefined(bool ID) { assert(isThisDeclarationADefinition() && - "Can only set the implicit-definition flag once the destructor has been defined"); + "Can only set the implicit-definition flag once the destructor has " + "been defined"); ImplicitlyDefined = ID; } @@ -1976,7 +2220,7 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const CXXDestructorDecl *D) { return true; } static bool classofKind(Kind K) { return K == CXXDestructor; } - + friend class ASTDeclReader; friend class ASTDeclWriter; }; @@ -1991,7 +2235,8 @@ public: /// }; /// @endcode class CXXConversionDecl : public CXXMethodDecl { - /// IsExplicitSpecified - Whether this conversion function declaration is + virtual void anchor(); + /// IsExplicitSpecified - Whether this conversion function declaration is /// marked "explicit", meaning that it can only be applied when the user /// explicitly wrote a cast. This is a C++0x feature. bool IsExplicitSpecified : 1; @@ -2006,7 +2251,6 @@ class CXXConversionDecl : public CXXMethodDecl { IsExplicitSpecified(isExplicitSpecified) { } public: - static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty); static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, @@ -2014,8 +2258,9 @@ public: bool isInline, bool isExplicit, bool isConstexpr, SourceLocation EndLocation); + static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID); - /// IsExplicitSpecified - Whether this conversion function declaration is + /// IsExplicitSpecified - Whether this conversion function declaration is /// marked "explicit", meaning that it can only be applied when the user /// explicitly wrote a cast. This is a C++0x feature. bool isExplicitSpecified() const { return IsExplicitSpecified; } @@ -2034,11 +2279,15 @@ public: return getType()->getAs<FunctionType>()->getResultType(); } + /// \brief Determine whether this conversion function is a conversion from + /// a lambda closure type to a block pointer. + bool isLambdaToBlockPointerConversion() const; + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const CXXConversionDecl *D) { return true; } static bool classofKind(Kind K) { return K == CXXConversion; } - + friend class ASTDeclReader; friend class ASTDeclWriter; }; @@ -2047,6 +2296,7 @@ public: /// extern "C" void foo(); /// class LinkageSpecDecl : public Decl, public DeclContext { + virtual void anchor(); public: /// LanguageIDs - Used to represent the language in a linkage /// specification. The values are part of the serialization abi for @@ -2076,7 +2326,8 @@ public: SourceLocation ExternLoc, SourceLocation LangLoc, LanguageIDs Lang, SourceLocation RBraceLoc = SourceLocation()); - + static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); + /// \brief Return the language specified by this linkage specification. LanguageIDs getLanguage() const { return Language; } /// \brief Set the language specified by this linkage specification. @@ -2091,7 +2342,7 @@ public: void setExternLoc(SourceLocation L) { ExternLoc = L; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } - SourceLocation getLocEnd() const { + SourceLocation getLocEnd() const LLVM_READONLY { if (hasBraces()) return getRBraceLoc(); // No braces: get the end location of the (only) declaration in context @@ -2099,7 +2350,7 @@ public: return decls_empty() ? getLocation() : decls_begin()->getLocEnd(); } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(ExternLoc, getLocEnd()); } @@ -2119,12 +2370,13 @@ public: /// using namespace std; /// // NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide -// artificial name, for all using-directives in order to store +// artificial names for all using-directives in order to store // them in DeclContext effectively. class UsingDirectiveDecl : public NamedDecl { + virtual void anchor(); /// \brief The location of the "using" keyword. SourceLocation UsingLoc; - + /// SourceLocation - Location of 'namespace' token. SourceLocation NamespaceLoc; @@ -2159,11 +2411,11 @@ public: /// \brief Retrieve the nested-name-specifier that qualifies the /// name of the namespace, with source-location information. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } - + /// \brief Retrieve the nested-name-specifier that qualifies the /// name of the namespace. - NestedNameSpecifier *getQualifier() const { - return QualifierLoc.getNestedNameSpecifier(); + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); } NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; } @@ -2185,7 +2437,7 @@ public: /// \brief Return the location of the "using" keyword. SourceLocation getUsingLoc() const { return UsingLoc; } - + // FIXME: Could omit 'Key' in name. /// getNamespaceKeyLocation - Returns location of namespace keyword. SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; } @@ -2200,18 +2452,19 @@ public: SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor); - - SourceRange getSourceRange() const { + static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(UsingLoc, getLocation()); } - + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const UsingDirectiveDecl *D) { return true; } static bool classofKind(Kind K) { return K == UsingDirective; } // Friend for getUsingDirectiveName. friend class DeclContext; - + friend class ASTDeclReader; }; @@ -2221,15 +2474,17 @@ public: /// namespace Foo = Bar; /// @endcode class NamespaceAliasDecl : public NamedDecl { + virtual void anchor(); + /// \brief The location of the "namespace" keyword. SourceLocation NamespaceLoc; /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc. SourceLocation IdentLoc; - + /// \brief The nested-name-specifier that precedes the namespace. NestedNameSpecifierLoc QualifierLoc; - + /// Namespace - The Decl that this alias points to. Can either be a /// NamespaceDecl or a NamespaceAliasDecl. NamedDecl *Namespace; @@ -2238,23 +2493,23 @@ class NamespaceAliasDecl : public NamedDecl { SourceLocation AliasLoc, IdentifierInfo *Alias, NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Namespace) - : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias), + : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias), NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc), QualifierLoc(QualifierLoc), Namespace(Namespace) { } friend class ASTDeclReader; - + public: /// \brief Retrieve the nested-name-specifier that qualifies the /// name of the namespace, with source-location information. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } - + /// \brief Retrieve the nested-name-specifier that qualifies the /// name of the namespace. - NestedNameSpecifier *getQualifier() const { - return QualifierLoc.getNestedNameSpecifier(); + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); } - + /// \brief Retrieve the namespace declaration aliased by this directive. NamespaceDecl *getNamespace() { if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace)) @@ -2282,17 +2537,19 @@ public: NamedDecl *getAliasedNamespace() const { return Namespace; } static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation NamespaceLoc, + SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Namespace); - virtual SourceRange getSourceRange() const { + static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + virtual SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(NamespaceLoc, IdentLoc); } - + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const NamespaceAliasDecl *D) { return true; } static bool classofKind(Kind K) { return K == NamespaceAlias; } @@ -2310,6 +2567,8 @@ public: /// } /// class UsingShadowDecl : public NamedDecl { + virtual void anchor(); + /// The referenced declaration. NamedDecl *Underlying; @@ -2337,6 +2596,8 @@ public: return new (C) UsingShadowDecl(DC, Loc, Using, Target); } + static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID); + /// \brief Gets the underlying declaration which has been brought into the /// local scope. NamedDecl *getTargetDecl() const { return Underlying; } @@ -2369,6 +2630,8 @@ public: /// UsingDecl - Represents a C++ using-declaration. For example: /// using someNameSpace::someIdentifier; class UsingDecl : public NamedDecl { + virtual void anchor(); + /// \brief The source location of the "using" location itself. SourceLocation UsingLocation; @@ -2380,18 +2643,16 @@ class UsingDecl : public NamedDecl { DeclarationNameLoc DNLoc; /// \brief The first shadow declaration of the shadow decl chain associated - /// with this using declaration. - UsingShadowDecl *FirstUsingShadow; + /// with this using declaration. The bool member of the pair store whether + /// this decl has the 'typename' keyword. + llvm::PointerIntPair<UsingShadowDecl *, 1, bool> FirstUsingShadow; - // \brief Has 'typename' keyword. - bool IsTypeName; - - UsingDecl(DeclContext *DC, SourceLocation UL, + UsingDecl(DeclContext *DC, SourceLocation UL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool IsTypeNameArg) : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()), UsingLocation(UL), QualifierLoc(QualifierLoc), - DNLoc(NameInfo.getInfo()), FirstUsingShadow(0),IsTypeName(IsTypeNameArg) { + DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, IsTypeNameArg) { } public: @@ -2406,8 +2667,8 @@ public: NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } /// \brief Retrieve the nested-name-specifier that qualifies the name. - NestedNameSpecifier *getQualifier() const { - return QualifierLoc.getNestedNameSpecifier(); + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); } DeclarationNameInfo getNameInfo() const { @@ -2415,10 +2676,10 @@ public: } /// \brief Return true if the using declaration has 'typename'. - bool isTypeName() const { return IsTypeName; } + bool isTypeName() const { return FirstUsingShadow.getInt(); } /// \brief Sets whether the using declaration has 'typename'. - void setTypeName(bool TN) { IsTypeName = TN; } + void setTypeName(bool TN) { FirstUsingShadow.setInt(TN); } /// \brief Iterates through the using shadow declarations assosiated with /// this using declaration. @@ -2459,7 +2720,7 @@ public: }; shadow_iterator shadow_begin() const { - return shadow_iterator(FirstUsingShadow); + return shadow_iterator(FirstUsingShadow.getPointer()); } shadow_iterator shadow_end() const { return shadow_iterator(); } @@ -2478,7 +2739,9 @@ public: const DeclarationNameInfo &NameInfo, bool IsTypeNameArg); - SourceRange getSourceRange() const { + static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(UsingLocation, getNameInfo().getEndLoc()); } @@ -2499,6 +2762,8 @@ public: /// using Base<T>::foo; /// }; class UnresolvedUsingValueDecl : public ValueDecl { + virtual void anchor(); + /// \brief The source location of the 'using' keyword SourceLocation UsingLocation; @@ -2510,7 +2775,7 @@ class UnresolvedUsingValueDecl : public ValueDecl { DeclarationNameLoc DNLoc; UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty, - SourceLocation UsingLoc, + SourceLocation UsingLoc, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) : ValueDecl(UnresolvedUsingValue, DC, @@ -2531,20 +2796,23 @@ public: NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } /// \brief Retrieve the nested-name-specifier that qualifies the name. - NestedNameSpecifier *getQualifier() const { - return QualifierLoc.getNestedNameSpecifier(); + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); } - + DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } static UnresolvedUsingValueDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, - NestedNameSpecifierLoc QualifierLoc, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo); - SourceRange getSourceRange() const { + static UnresolvedUsingValueDecl * + CreateDeserialized(ASTContext &C, unsigned ID); + + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(UsingLocation, getNameInfo().getEndLoc()); } @@ -2566,6 +2834,8 @@ public: /// The type associated with a unresolved using typename decl is /// currently always a typename type. class UnresolvedUsingTypenameDecl : public TypeDecl { + virtual void anchor(); + /// \brief The source location of the 'using' keyword SourceLocation UsingLocation; @@ -2578,14 +2848,14 @@ class UnresolvedUsingTypenameDecl : public TypeDecl { UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc, SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc, - SourceLocation TargetNameLoc, + SourceLocation TargetNameLoc, IdentifierInfo *TargetName) : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName, UsingLoc), TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { } friend class ASTDeclReader; - + public: /// \brief Returns the source location of the 'using' keyword. SourceLocation getUsingLoc() const { return getLocStart(); } @@ -2598,8 +2868,8 @@ public: NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } /// \brief Retrieve the nested-name-specifier that qualifies the name. - NestedNameSpecifier *getQualifier() const { - return QualifierLoc.getNestedNameSpecifier(); + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); } static UnresolvedUsingTypenameDecl * @@ -2607,6 +2877,9 @@ public: SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TargetNameLoc, DeclarationName TargetName); + static UnresolvedUsingTypenameDecl * + CreateDeserialized(ASTContext &C, unsigned ID); + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; } static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; } @@ -2614,6 +2887,7 @@ public: /// StaticAssertDecl - Represents a C++0x static_assert declaration. class StaticAssertDecl : public Decl { + virtual void anchor(); Expr *AssertExpr; StringLiteral *Message; SourceLocation RParenLoc; @@ -2629,7 +2903,8 @@ public: SourceLocation StaticAssertLoc, Expr *AssertExpr, StringLiteral *Message, SourceLocation RParenLoc); - + static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID); + Expr *getAssertExpr() { return AssertExpr; } const Expr *getAssertExpr() const { return AssertExpr; } @@ -2639,7 +2914,7 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getLocation(), getRParenLoc()); } @@ -2655,6 +2930,9 @@ public: const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, AccessSpecifier AS); +const PartialDiagnostic &operator<<(const PartialDiagnostic &DB, + AccessSpecifier AS); + } // end namespace clang #endif |