diff options
author | dim <dim@FreeBSD.org> | 2011-05-02 19:39:53 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-05-02 19:39:53 +0000 |
commit | 110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab (patch) | |
tree | 64a10f4c4154739d4a8191d7e1b52ce497f4ebd6 /include/clang/AST/DeclCXX.h | |
parent | a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51 (diff) | |
download | FreeBSD-src-110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab.zip FreeBSD-src-110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab.tar.gz |
Vendor import of clang trunk r130700:
http://llvm.org/svn/llvm-project/cfe/trunk@130700
Diffstat (limited to 'include/clang/AST/DeclCXX.h')
-rw-r--r-- | include/clang/AST/DeclCXX.h | 351 |
1 files changed, 258 insertions, 93 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 1656a7e..8c819e3 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -306,6 +306,37 @@ class CXXRecordDecl : public RecordDecl { /// one pure virtual function, (that can come from a base class). bool Abstract : 1; + /// IsStandardLayout - True when this class has standard layout. + /// + /// C++0x [class]p7. A standard-layout class is a class that: + /// * 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 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 + /// classes with non-static data members, and + /// * has no base classes of the same type as the first non-static data + /// member. + bool IsStandardLayout : 1; + + /// HasNoNonEmptyBases - True when there are no non-empty base classes. + /// + /// This is a helper bit of state used to implement IsStandardLayout more + /// efficiently. + bool HasNoNonEmptyBases : 1; + + /// HasPrivateFields - True when there are private non-static data members. + bool HasPrivateFields : 1; + + /// HasProtectedFields - True when there are protected non-static data + /// members. + bool HasProtectedFields : 1; + + /// HasPublicFields - True when there are private non-static data members. + bool HasPublicFields : 1; + /// HasTrivialConstructor - True when this class has a trivial constructor. /// /// C++ [class.ctor]p5. A constructor is trivial if it is an @@ -316,31 +347,71 @@ class CXXRecordDecl : public RecordDecl { /// (or array thereof), each such class has a trivial constructor. bool HasTrivialConstructor : 1; + /// HasConstExprNonCopyMoveConstructor - True when this class has at least + /// one constexpr constructor which is neither the copy nor move + /// constructor. + bool HasConstExprNonCopyMoveConstructor : 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. + /// C++0x [class.copy]p13: + /// A copy/move constructor for class X is trivial if it is neither + /// user-provided nor deleted and if + /// -- class X has no virtual functions and no virtual base classes, and + /// -- the constructor selected to copy/move each direct base class + /// subobject is trivial, and + /// -- for each non-static data member of X that is of class type (or an + /// array thereof), the constructor selected to copy/move that member + /// is trivial; + /// otherwise the copy/move constructor is non-trivial. bool HasTrivialCopyConstructor : 1; + /// HasTrivialMoveConstructor - True when this class has a trivial move + /// constructor. + /// + /// C++0x [class.copy]p13: + /// A copy/move constructor for class X is trivial if it is neither + /// user-provided nor deleted and if + /// -- class X has no virtual functions and no virtual base classes, and + /// -- the constructor selected to copy/move each direct base class + /// subobject is trivial, and + /// -- for each non-static data member of X that is of class type (or an + /// array thereof), the constructor selected to copy/move that member + /// is trivial; + /// otherwise the copy/move constructor is non-trivial. + bool HasTrivialMoveConstructor : 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. + /// C++0x [class.copy]p27: + /// A copy/move assignment operator for class X is trivial if it is + /// neither user-provided nor deleted and if + /// -- class X has no virtual functions and no virtual base classes, and + /// -- the assignment operator selected to copy/move each direct base + /// class subobject is trivial, and + /// -- for each non-static data member of X that is of class type (or an + /// array thereof), the assignment operator selected to copy/move + /// that member is trivial; + /// otherwise the copy/move assignment operator is non-trivial. bool HasTrivialCopyAssignment : 1; + /// HasTrivialMoveAssignment - True when this class has a trivial move + /// assignment operator. + /// + /// C++0x [class.copy]p27: + /// A copy/move assignment operator for class X is trivial if it is + /// neither user-provided nor deleted and if + /// -- class X has no virtual functions and no virtual base classes, and + /// -- the assignment operator selected to copy/move each direct base + /// class subobject is trivial, and + /// -- for each non-static data member of X that is of class type (or an + /// array thereof), the assignment operator selected to copy/move + /// that member is trivial; + /// otherwise the copy/move assignment operator is non-trivial. + bool HasTrivialMoveAssignment : 1; + /// HasTrivialDestructor - True when this class has a trivial destructor. /// /// C++ [class.dtor]p3. A destructor is trivial if it is an @@ -351,6 +422,10 @@ class CXXRecordDecl : public RecordDecl { /// type (or array thereof), each such class has a trivial destructor. bool HasTrivialDestructor : 1; + /// HasNonLiteralTypeFieldsOrBases - True when this class contains at least + /// one non-static data member or base class of non literal type. + bool HasNonLiteralTypeFieldsOrBases : 1; + /// ComputedVisibleConversions - True when visible conversion functions are /// already computed and are available. bool ComputedVisibleConversions : 1; @@ -449,9 +524,8 @@ class CXXRecordDecl : public RecordDecl { protected: CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - CXXRecordDecl *PrevDecl, - SourceLocation TKL = SourceLocation()); + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, CXXRecordDecl *PrevDecl); public: /// base_class_iterator - Iterator that traverses the base classes @@ -494,9 +568,8 @@ public: bool hasDefinition() const { return DefinitionData != 0; } static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - SourceLocation TKL = SourceLocation(), - CXXRecordDecl* PrevDecl=0, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0, bool DelayTypeCreation = false); static CXXRecordDecl *Create(const ASTContext &C, EmptyShell Empty); @@ -723,26 +796,58 @@ public: /// which means that the class contains or inherits a pure virtual function. bool isAbstract() const { return data().Abstract; } + /// isStandardLayout - Whether this class has standard layout + /// (C++ [class]p7) + bool isStandardLayout() const { return data().IsStandardLayout; } + // hasTrivialConstructor - Whether this class has a trivial constructor // (C++ [class.ctor]p5) bool hasTrivialConstructor() const { return data().HasTrivialConstructor; } + // hasConstExprNonCopyMoveConstructor - Whether this class has at least one + // constexpr constructor other than the copy or move constructors + bool hasConstExprNonCopyMoveConstructor() const { + return data().HasConstExprNonCopyMoveConstructor; + } + // hasTrivialCopyConstructor - Whether this class has a trivial copy - // constructor (C++ [class.copy]p6) + // constructor (C++ [class.copy]p6, C++0x [class.copy]p13) bool hasTrivialCopyConstructor() const { return data().HasTrivialCopyConstructor; } + // hasTrivialMoveConstructor - Whether this class has a trivial move + // constructor (C++0x [class.copy]p13) + bool hasTrivialMoveConstructor() const { + return data().HasTrivialMoveConstructor; + } + // hasTrivialCopyAssignment - Whether this class has a trivial copy - // assignment operator (C++ [class.copy]p11) + // assignment operator (C++ [class.copy]p11, C++0x [class.copy]p27) bool hasTrivialCopyAssignment() const { return data().HasTrivialCopyAssignment; } + // hasTrivialMoveAssignment - Whether this class has a trivial move + // assignment operator (C++0x [class.copy]p27) + bool hasTrivialMoveAssignment() const { + return data().HasTrivialMoveAssignment; + } + // hasTrivialDestructor - Whether this class has a trivial destructor // (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. + bool hasNonLiteralTypeFieldsOrBases() const { + return data().HasNonLiteralTypeFieldsOrBases; + } + + // isTriviallyCopyable - Whether this class is considered trivially copyable + // (C++0x [class]p5). + bool isTriviallyCopyable() const; + /// \brief If this record is an instantiation of a member class, /// retrieves the member class from which it was instantiated. /// @@ -1034,20 +1139,27 @@ public: /// struct/union/class. class CXXMethodDecl : public FunctionDecl { protected: - CXXMethodDecl(Kind DK, CXXRecordDecl *RD, + CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isStatic, StorageClass SCAsWritten, bool isInline) - : FunctionDecl(DK, RD, NameInfo, T, TInfo, (isStatic ? SC_Static : SC_None), - SCAsWritten, isInline) {} + bool isStatic, StorageClass SCAsWritten, bool isInline, + SourceLocation EndLocation) + : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo, + (isStatic ? SC_Static : SC_None), + SCAsWritten, isInline) { + if (EndLocation.isValid()) + setRangeEnd(EndLocation); + } public: static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD, + SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isStatic = false, - StorageClass SCAsWritten = SC_None, - bool isInline = false); + bool isStatic, + StorageClass SCAsWritten, + bool isInline, + SourceLocation EndLocation); bool isStatic() const { return getStorageClass() == SC_Static; } bool isInstance() const { return !isStatic(); } @@ -1148,13 +1260,16 @@ public: /// @endcode class CXXCtorInitializer { /// \brief Either the base class name (stored as a TypeSourceInfo*), an normal - /// field (FieldDecl) or an anonymous field (IndirectFieldDecl*) being - /// initialized. - llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *> + /// field (FieldDecl), anonymous field (IndirectFieldDecl*), or target + /// constructor (CXXConstructorDecl*) being initialized. + llvm::PointerUnion4<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *, + CXXConstructorDecl *> Initializee; /// \brief The source location for the field name or, for a base initializer - /// pack expansion, the location of the ellipsis. + /// 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 @@ -1199,11 +1314,17 @@ public: SourceLocation MemberLoc, SourceLocation L, Expr *Init, SourceLocation R); + /// CXXCtorInitializer - Creates a new anonymous field initializer. explicit CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member, SourceLocation MemberLoc, SourceLocation L, Expr *Init, SourceLocation R); + /// CXXCtorInitializer - Creates a new delegating Initializer. + explicit + CXXCtorInitializer(ASTContext &Context, SourceLocation D, SourceLocation L, + CXXConstructorDecl *Target, Expr *Init, SourceLocation R); + /// \brief Creates a new member initializer that optionally contains /// array indices used to describe an elementwise initialization. static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member, @@ -1227,6 +1348,12 @@ public: return Initializee.is<IndirectFieldDecl*>(); } + /// isDelegatingInitializer - Returns true when this initializer is creating + /// a delegating constructor. + bool isDelegatingInitializer() const { + return Initializee.is<CXXConstructorDecl *>(); + } + /// \brief Determine whether this initializer is a pack expansion. bool isPackExpansion() const { return isBaseInitializer() && MemberOrEllipsisLocation.isValid(); @@ -1284,6 +1411,13 @@ public: return 0; } + CXXConstructorDecl *getTargetConstructor() const { + if (isDelegatingInitializer()) + return Initializee.get<CXXConstructorDecl*>(); + else + return 0; + } + SourceLocation getMemberLocation() const { return MemberOrEllipsisLocation; } @@ -1373,12 +1507,13 @@ class CXXConstructorDecl : public CXXMethodDecl { CXXCtorInitializer **CtorInitializers; unsigned NumCtorInitializers; - CXXConstructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo, + CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXConstructor, RD, NameInfo, T, TInfo, false, - SC_None, isInline), + : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, false, + SC_None, isInline, SourceLocation()), IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false), CtorInitializers(0), NumCtorInitializers(0) { setImplicit(isImplicitlyDeclared); @@ -1387,6 +1522,7 @@ class CXXConstructorDecl : public CXXMethodDecl { public: static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty); static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, + SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicit, @@ -1472,6 +1608,23 @@ public: void setCtorInitializers(CXXCtorInitializer ** initializers) { CtorInitializers = initializers; } + + /// isDelegatingConstructor - Whether this constructor is a + /// delegating constructor + bool isDelegatingConstructor() const { + return (getNumCtorInitializers() == 1) && + CtorInitializers[0]->isDelegatingInitializer(); + } + + /// getTargetConstructor - When this constructor delegates to + /// another, retrieve the target + CXXConstructorDecl *getTargetConstructor() const { + if (isDelegatingConstructor()) + return CtorInitializers[0]->getTargetConstructor(); + else + return 0; + } + /// isDefaultConstructor - Whether this constructor is a default /// constructor (C++ [class.ctor]p5), which can be used to /// default-initialize a class of this type. @@ -1508,8 +1661,11 @@ public: /// \brief Determine whether this constructor is a move constructor /// (C++0x [class.copy]p3), which can be used to move values of the class. - bool isMoveConstructor() const; - + bool isMoveConstructor() const { + unsigned TypeQuals = 0; + return isMoveConstructor(TypeQuals); + } + /// \brief Determine whether this is a copy or move constructor. /// /// \param TypeQuals Will be set to the type qualifiers on the reference @@ -1567,11 +1723,12 @@ class CXXDestructorDecl : public CXXMethodDecl { FunctionDecl *OperatorDelete; - CXXDestructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo, + CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXDestructor, RD, NameInfo, T, TInfo, false, - SC_None, isInline), + : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, false, + SC_None, isInline, SourceLocation()), ImplicitlyDefined(false), OperatorDelete(0) { setImplicit(isImplicitlyDeclared); } @@ -1579,6 +1736,7 @@ 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, @@ -1629,19 +1787,23 @@ class CXXConversionDecl : public CXXMethodDecl { /// explicitly wrote a cast. This is a C++0x feature. bool IsExplicitSpecified : 1; - CXXConversionDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo, + CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isInline, bool isExplicitSpecified) - : CXXMethodDecl(CXXConversion, RD, NameInfo, T, TInfo, false, - SC_None, isInline), + bool isInline, bool isExplicitSpecified, + SourceLocation EndLocation) + : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, false, + SC_None, isInline, EndLocation), IsExplicitSpecified(isExplicitSpecified) { } public: static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty); static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, + SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isInline, bool isExplicit); + bool isInline, bool isExplicit, + SourceLocation EndLocation); /// IsExplicitSpecified - Whether this conversion function declaration is /// marked "explicit", meaning that it can only be applied when the user @@ -1688,33 +1850,48 @@ public: private: /// Language - The language for this linkage specification. LanguageIDs Language; + /// ExternLoc - The source location for the extern keyword. + SourceLocation ExternLoc; + /// RBraceLoc - The source location for the right brace (if valid). + SourceLocation RBraceLoc; - /// 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) { } + LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc, + SourceLocation LangLoc, LanguageIDs lang, + SourceLocation RBLoc) + : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec), + Language(lang), ExternLoc(ExternLoc), RBraceLoc(RBLoc) { } public: static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, LanguageIDs Lang, - bool Braces); + SourceLocation ExternLoc, + SourceLocation LangLoc, LanguageIDs Lang, + SourceLocation RBraceLoc = SourceLocation()); /// \brief Return the language specified by this linkage specification. LanguageIDs getLanguage() const { return Language; } - /// \brief Set the language specified by this linkage specification. void setLanguage(LanguageIDs L) { Language = L; } /// \brief Determines whether this linkage specification had braces in /// its syntactic form. - bool hasBraces() const { return HadBraces; } + bool hasBraces() const { return RBraceLoc.isValid(); } - /// \brief Set whether this linkage specification has braces in its - /// syntactic form. - void setHasBraces(bool B) { HadBraces = B; } + SourceLocation getExternLoc() const { return ExternLoc; } + SourceLocation getRBraceLoc() const { return RBraceLoc; } + void setExternLoc(SourceLocation L) { ExternLoc = L; } + void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } + + SourceLocation getLocEnd() const { + if (hasBraces()) + return getRBraceLoc(); + // No braces: get the end location of the (only) declaration in context + // (if present). + return decls_empty() ? getLocation() : decls_begin()->getLocEnd(); + } + + SourceRange getSourceRange() const { + return SourceRange(ExternLoc, getLocEnd()); + } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const LinkageSpecDecl *D) { return true; } @@ -2023,12 +2200,6 @@ public: return QualifierLoc.getNestedNameSpecifier(); } - /// \brief Retrieve the source range of the nested-name-specifier - /// that qualifies the name. - SourceRange getQualifierRange() const { - return QualifierLoc.getSourceRange(); - } - DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } @@ -2154,12 +2325,6 @@ public: return QualifierLoc.getNestedNameSpecifier(); } - /// \brief Retrieve the source range of the nested-name-specifier - /// that qualifies the name. - SourceRange getQualifierRange() const { - return QualifierLoc.getSourceRange(); - } - DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } @@ -2205,15 +2370,15 @@ class UnresolvedUsingTypenameDecl : public TypeDecl { NestedNameSpecifierLoc QualifierLoc, SourceLocation TargetNameLoc, IdentifierInfo *TargetName) - : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName), - UsingLocation(UsingLoc), TypenameLocation(TypenameLoc), - QualifierLoc(QualifierLoc) { } + : 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 UsingLocation; } + SourceLocation getUsingLoc() const { return getLocStart(); } /// \brief Returns the source location of the 'typename' keyword. SourceLocation getTypenameLoc() const { return TypenameLocation; } @@ -2227,22 +2392,11 @@ public: return QualifierLoc.getNestedNameSpecifier(); } - /// \brief Retrieve the source range of the nested-name-specifier - /// that qualifies the name. - SourceRange getQualifierRange() const { - return QualifierLoc.getSourceRange(); - } - - // FIXME: DeclarationNameInfo static UnresolvedUsingTypenameDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TargetNameLoc, DeclarationName TargetName); - SourceRange getSourceRange() const { - return SourceRange(UsingLocation, getLocation()); - } - 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; } @@ -2252,15 +2406,19 @@ public: class StaticAssertDecl : public Decl { Expr *AssertExpr; StringLiteral *Message; + SourceLocation RParenLoc; - StaticAssertDecl(DeclContext *DC, SourceLocation L, - Expr *assertexpr, StringLiteral *message) - : Decl(StaticAssert, DC, L), AssertExpr(assertexpr), Message(message) { } + StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc, + Expr *assertexpr, StringLiteral *message, + SourceLocation RParenLoc) + : Decl(StaticAssert, DC, StaticAssertLoc), AssertExpr(assertexpr), + Message(message), RParenLoc(RParenLoc) { } public: static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, Expr *AssertExpr, - StringLiteral *Message); + SourceLocation StaticAssertLoc, + Expr *AssertExpr, StringLiteral *Message, + SourceLocation RParenLoc); Expr *getAssertExpr() { return AssertExpr; } const Expr *getAssertExpr() const { return AssertExpr; } @@ -2268,6 +2426,13 @@ public: StringLiteral *getMessage() { return Message; } const StringLiteral *getMessage() const { return Message; } + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + + SourceRange getSourceRange() const { + return SourceRange(getLocation(), getRParenLoc()); + } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(StaticAssertDecl *D) { return true; } static bool classofKind(Kind K) { return K == StaticAssert; } |