diff options
Diffstat (limited to 'include/clang/AST/Decl.h')
-rw-r--r-- | include/clang/AST/Decl.h | 135 |
1 files changed, 102 insertions, 33 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 109036f9588e..b2e332d6d85c 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -251,7 +251,7 @@ public: // FIXME: Deprecated, move clients to getName(). std::string getNameAsString() const { return Name.getAsString(); } - void printName(raw_ostream &os) const { os << Name; } + virtual void printName(raw_ostream &os) const; /// getDeclName - Get the actual, stored name of the declaration, /// which may be a special name. @@ -789,7 +789,7 @@ public: protected: // A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we - // have allocated the auxilliary struct of information there. + // have allocated the auxiliary struct of information there. // // TODO: It is a bit unfortunate to use a PointerUnion inside the VarDecl for // this as *many* VarDecls are ParmVarDecls that don't have default @@ -865,6 +865,11 @@ protected: unsigned : NumVarDeclBits; + // FIXME: We need something similar to CXXRecordDecl::DefinitionData. + /// \brief Whether this variable is a definition which was demoted due to + /// module merge. + unsigned IsThisDeclarationADemotedDefinition : 1; + /// \brief Whether this variable is the exception variable in a C++ catch /// or an Objective-C @catch statement. unsigned ExceptionVar : 1; @@ -1025,7 +1030,7 @@ public: /// void foo() { int x; static int y; extern int z; } /// bool isLocalVarDecl() const { - if (getKind() != Decl::Var) + if (getKind() != Decl::Var && getKind() != Decl::Decomposition) return false; if (const DeclContext *DC = getLexicalDeclContext()) return DC->getRedeclContext()->isFunctionOrMethod(); @@ -1040,7 +1045,7 @@ public: /// isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but /// excludes variables declared in blocks. bool isFunctionOrMethodVarDecl() const { - if (getKind() != Decl::Var) + if (getKind() != Decl::Var && getKind() != Decl::Decomposition) return false; const DeclContext *DC = getLexicalDeclContext()->getRedeclContext(); return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block; @@ -1198,12 +1203,28 @@ public: InitializationStyle getInitStyle() const { return static_cast<InitializationStyle>(VarDeclBits.InitStyle); } - /// \brief Whether the initializer is a direct-initializer (list or call). bool isDirectInit() const { return getInitStyle() != CInit; } + /// \brief If this definition should pretend to be a declaration. + bool isThisDeclarationADemotedDefinition() const { + return isa<ParmVarDecl>(this) ? false : + NonParmVarDeclBits.IsThisDeclarationADemotedDefinition; + } + + /// \brief This is a definition which should be demoted to a declaration. + /// + /// In some cases (mostly module merging) we can end up with two visible + /// definitions one of which needs to be demoted to a declaration to keep + /// the AST invariants. + void demoteThisDefinitionToDeclaration() { + assert (isThisDeclarationADefinition() && "Not a definition!"); + assert (!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!"); + NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1; + } + /// \brief Determine whether this variable is the exception variable in a /// C++ catch statememt or an Objective-C \@catch statement. bool isExceptionVariable() const { @@ -1302,6 +1323,10 @@ public: NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same; } + /// \brief Retrieve the variable declaration from which this variable could + /// be instantiated, if it is an instantiation (rather than a non-template). + VarDecl *getTemplateInstantiationPattern() const; + /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member /// from which it was instantiated. @@ -1576,11 +1601,6 @@ private: /// no formals. ParmVarDecl **ParamInfo; - /// DeclsInPrototypeScope - Array of pointers to NamedDecls for - /// decls defined in the function prototype that are not parameters. E.g. - /// 'enum Y' in 'void f(enum Y {AA} x) {}'. - ArrayRef<NamedDecl *> DeclsInPrototypeScope; - LazyDeclStmtPtr Body; // FIXME: This can be packed into the bitfields in DeclContext. @@ -1607,6 +1627,11 @@ private: /// skipped. unsigned HasSkippedBody : 1; + /// Indicates if the function declaration will have a body, once we're done + /// parsing it. (We don't set it to false when we're done parsing, in the + /// hopes this is simpler.) + unsigned WillHaveBody : 1; + /// \brief End part of this FunctionDecl's source range. /// /// We could compute the full range in getSourceRange(). However, when we're @@ -1676,25 +1701,21 @@ private: protected: FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - StorageClass S, bool isInlineSpecified, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified, bool isConstexprSpecified) - : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, - StartLoc), - DeclContext(DK), - redeclarable_base(C), - ParamInfo(nullptr), Body(), - SClass(S), - IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), - IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), - HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), - IsDefaulted(false), IsExplicitlyDefaulted(false), - HasImplicitReturnZero(false), IsLateTemplateParsed(false), - IsConstexpr(isConstexprSpecified), UsesSEHTry(false), - HasSkippedBody(false), EndRangeLoc(NameInfo.getEndLoc()), - TemplateOrSpecialization(), - DNLoc(NameInfo.getInfo()) {} + : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, + StartLoc), + DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(), + SClass(S), IsInline(isInlineSpecified), + IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false), + IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), + IsDeleted(false), IsTrivial(false), IsDefaulted(false), + IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), + IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified), + UsesSEHTry(false), HasSkippedBody(false), WillHaveBody(false), + EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), + DNLoc(NameInfo.getInfo()) {} typedef Redeclarable<FunctionDecl> redeclarable_base; FunctionDecl *getNextRedeclarationImpl() override { @@ -1976,6 +1997,10 @@ public: bool hasSkippedBody() const { return HasSkippedBody; } void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } + /// True if this function will eventually have a body, once it's fully parsed. + bool willHaveBody() const { return WillHaveBody; } + void setWillHaveBody(bool V = true) { WillHaveBody = V; } + void setPreviousDeclaration(FunctionDecl * PrevDecl); FunctionDecl *getCanonicalDecl() override; @@ -2020,11 +2045,6 @@ public: setParams(getASTContext(), NewParamInfo); } - ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const { - return DeclsInPrototypeScope; - } - void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls); - /// getMinRequiredArguments - Returns the minimum number of arguments /// needed to call this function. This may be fewer than the number of /// function parameters, if some of the parameters have default @@ -3784,6 +3804,55 @@ public: static bool classofKind(Kind K) { return K == Import; } }; +/// \brief Represents a C++ Modules TS module export declaration. +/// +/// For example: +/// \code +/// export void foo(); +/// \endcode +class ExportDecl final : public Decl, public DeclContext { + virtual void anchor(); +private: + /// \brief The source location for the right brace (if valid). + SourceLocation RBraceLoc; + + ExportDecl(DeclContext *DC, SourceLocation ExportLoc) + : Decl(Export, DC, ExportLoc), DeclContext(Export), + RBraceLoc(SourceLocation()) { } + + friend class ASTDeclReader; + +public: + static ExportDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation ExportLoc); + static ExportDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceLocation getExportLoc() const { return getLocation(); } + SourceLocation getRBraceLoc() const { return RBraceLoc; } + void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } + + SourceLocation getLocEnd() const LLVM_READONLY { + if (RBraceLoc.isValid()) + return RBraceLoc; + // No braces: get the end location of the (only) declaration in context + // (if present). + return decls_empty() ? getLocation() : decls_begin()->getLocEnd(); + } + + SourceRange getSourceRange() const override LLVM_READONLY { + return SourceRange(getLocation(), getLocEnd()); + } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Export; } + static DeclContext *castToDeclContext(const ExportDecl *D) { + return static_cast<DeclContext *>(const_cast<ExportDecl*>(D)); + } + static ExportDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast<ExportDecl *>(const_cast<DeclContext*>(DC)); + } +}; + /// \brief Represents an empty-declaration. class EmptyDecl : public Decl { virtual void anchor(); |