diff options
Diffstat (limited to 'include/clang/AST/Decl.h')
-rw-r--r-- | include/clang/AST/Decl.h | 311 |
1 files changed, 134 insertions, 177 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index e06b58b37be2..046ce70a343b 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -21,11 +21,13 @@ #include "clang/AST/Redeclarable.h" #include "clang/AST/Type.h" #include "clang/Basic/Linkage.h" +#include "clang/Basic/Module.h" #include "clang/Basic/OperatorKinds.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/TrailingObjects.h" namespace clang { struct ASTTemplateArgumentListInfo; @@ -37,7 +39,6 @@ class FunctionTemplateDecl; class FunctionTemplateSpecializationInfo; class LabelStmt; class MemberSpecializationInfo; -class Module; class NestedNameSpecifier; class ParmVarDecl; class Stmt; @@ -318,7 +319,8 @@ public: NamedDecl *getUnderlyingDecl() { // Fast-path the common case. if (this->getKind() != UsingShadow && - this->getKind() != ObjCCompatibleAlias) + this->getKind() != ObjCCompatibleAlias && + this->getKind() != NamespaceAlias) return this; return getUnderlyingDeclImpl(); @@ -462,25 +464,15 @@ public: } /// \brief Get the original (first) namespace declaration. - NamespaceDecl *getOriginalNamespace() { - if (isFirstDecl()) - return this; - - return AnonOrFirstNamespaceAndInline.getPointer(); - } + NamespaceDecl *getOriginalNamespace(); /// \brief Get the original (first) namespace declaration. - const NamespaceDecl *getOriginalNamespace() const { - if (isFirstDecl()) - return this; - - return AnonOrFirstNamespaceAndInline.getPointer(); - } + const NamespaceDecl *getOriginalNamespace() const; /// \brief Return true if this declaration is an original (first) declaration /// of the namespace. This is false for non-original (subsequent) namespace /// declarations and anonymous namespaces. - bool isOriginalNamespace() const { return isFirstDecl(); } + bool isOriginalNamespace() const; /// \brief Retrieve the anonymous namespace nested inside this namespace, /// if any. @@ -572,8 +564,7 @@ struct QualifierInfo { /// setTemplateParameterListsInfo - Sets info about "outer" template /// parameter lists. void setTemplateParameterListsInfo(ASTContext &Context, - unsigned NumTPLists, - TemplateParameterList **TPLists); + ArrayRef<TemplateParameterList *> TPLists); private: // Copy constructor and copy assignment are disabled. @@ -658,8 +649,8 @@ public: assert(index < getNumTemplateParameterLists()); return getExtInfo()->TemplParamLists[index]; } - void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists, - TemplateParameterList **TPLists); + void setTemplateParameterListsInfo(ASTContext &Context, + ArrayRef<TemplateParameterList *> TPLists); SourceLocation getTypeSpecStartLoc() const; @@ -728,17 +719,14 @@ public: }; protected: - /// \brief Placeholder type used in Init to denote an unparsed C++ default - /// argument. - struct UnparsedDefaultArgument; - - /// \brief Placeholder type used in Init to denote an uninstantiated C++ - /// default argument. - struct UninstantiatedDefaultArgument; - - typedef llvm::PointerUnion4<Stmt *, EvaluatedStmt *, - UnparsedDefaultArgument *, - UninstantiatedDefaultArgument *> InitType; + // A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we + // have allocated the auxilliary 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 + // arguments. We could save some space by moving this pointer union to be + // allocated in trailing space when necessary. + typedef llvm::PointerUnion<Stmt *, EvaluatedStmt *> InitType; /// \brief The initializer for this variable or, for a ParmVarDecl, the /// C++ default argument. @@ -762,6 +750,13 @@ private: protected: enum { NumParameterIndexBits = 8 }; + enum DefaultArgKind { + DAK_None, + DAK_Unparsed, + DAK_Uninstantiated, + DAK_Normal + }; + class ParmVarDeclBitfields { friend class ParmVarDecl; friend class ASTDeclReader; @@ -772,6 +767,12 @@ protected: /// prior declaration. unsigned HasInheritedDefaultArg : 1; + /// Describes the kind of default argument for this parameter. By default + /// this is none. If this is normal, then the default argument is stored in + /// the \c VarDecl initalizer expression unless we were unble to parse + /// (even an invalid) expression for the default argument. + unsigned DefaultArgKind : 2; + /// Whether this parameter undergoes K&R argument promotion. unsigned IsKNRPromoted : 1; @@ -815,6 +816,9 @@ protected: /// \brief Whether this variable is (C++0x) constexpr. unsigned IsConstexpr : 1; + /// \brief Whether this variable is a (C++ Concepts TS) concept. + unsigned IsConcept : 1; + /// \brief Whether this variable is the implicit variable for a lambda /// init-capture. unsigned IsInitCapture : 1; @@ -1062,47 +1066,14 @@ public: /// declaration it is attached to. Also get that declaration. const Expr *getAnyInitializer(const VarDecl *&D) const; - bool hasInit() const { - return !Init.isNull() && (Init.is<Stmt *>() || Init.is<EvaluatedStmt *>()); - } + bool hasInit() const; const Expr *getInit() const { - if (Init.isNull()) - return nullptr; - - const Stmt *S = Init.dyn_cast<Stmt *>(); - if (!S) { - if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>()) - S = ES->Value; - } - return (const Expr*) S; - } - Expr *getInit() { - if (Init.isNull()) - return nullptr; - - Stmt *S = Init.dyn_cast<Stmt *>(); - if (!S) { - if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>()) - S = ES->Value; - } - - return (Expr*) S; + return const_cast<VarDecl *>(this)->getInit(); } + Expr *getInit(); /// \brief Retrieve the address of the initializer expression. - Stmt **getInitAddress() { - if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>()) - return &ES->Value; - - // This union hack tip-toes around strict-aliasing rules. - union { - InitType *InitPtr; - Stmt **StmtPtr; - }; - - InitPtr = &Init; - return StmtPtr; - } + Stmt **getInitAddress(); void setInit(Expr *I); @@ -1124,33 +1095,18 @@ public: /// \brief Return the already-evaluated value of this variable's /// initializer, or NULL if the value is not yet known. Returns pointer /// to untyped APValue if the value could not be evaluated. - APValue *getEvaluatedValue() const { - if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) - if (Eval->WasEvaluated) - return &Eval->Evaluated; - - return nullptr; - } + APValue *getEvaluatedValue() const; /// \brief Determines whether it is already known whether the /// initializer is an integral constant expression or not. - bool isInitKnownICE() const { - if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) - return Eval->CheckedICE; - - return false; - } + bool isInitKnownICE() const; /// \brief Determines whether the initializer is an integral constant /// expression, or in C++11, whether the initializer is a constant /// expression. /// /// \pre isInitKnownICE() - bool isInitICE() const { - assert(isInitKnownICE() && - "Check whether we already know that the initializer is an ICE"); - return Init.get<EvaluatedStmt *>()->IsICE; - } + bool isInitICE() const; /// \brief Determine whether the value of the initializer attached to this /// declaration is an integral constant expression. @@ -1238,6 +1194,15 @@ public: NonParmVarDeclBits.IsConstexpr = IC; } + /// Whether this variable is (C++ Concepts TS) concept. + bool isConcept() const { + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConcept; + } + void setConcept(bool IC) { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.IsConcept = IC; + } + /// Whether this variable is the implicit variable for a lambda init-capture. bool isInitCapture() const { return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture; @@ -1342,6 +1307,7 @@ protected: TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg) : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) { assert(ParmVarDeclBits.HasInheritedDefaultArg == false); + assert(ParmVarDeclBits.DefaultArgKind == DAK_None); assert(ParmVarDeclBits.IsKNRPromoted == false); assert(ParmVarDeclBits.IsObjCMethodParam == false); setDefaultArg(DefArg); @@ -1416,29 +1382,20 @@ public: return const_cast<ParmVarDecl *>(this)->getDefaultArg(); } - void setDefaultArg(Expr *defarg) { - Init = reinterpret_cast<Stmt *>(defarg); - } + void setDefaultArg(Expr *defarg); /// \brief Retrieve the source range that covers the entire default /// argument. SourceRange getDefaultArgRange() const; - void setUninstantiatedDefaultArg(Expr *arg) { - Init = reinterpret_cast<UninstantiatedDefaultArgument *>(arg); - } - Expr *getUninstantiatedDefaultArg() { - return (Expr *)Init.get<UninstantiatedDefaultArgument *>(); - } + void setUninstantiatedDefaultArg(Expr *arg); + Expr *getUninstantiatedDefaultArg(); const Expr *getUninstantiatedDefaultArg() const { - return (const Expr *)Init.get<UninstantiatedDefaultArgument *>(); + return const_cast<ParmVarDecl *>(this)->getUninstantiatedDefaultArg(); } /// hasDefaultArg - Determines whether this parameter has a default argument, /// either parsed or not. - bool hasDefaultArg() const { - return getInit() || hasUnparsedDefaultArg() || - hasUninstantiatedDefaultArg(); - } + bool hasDefaultArg() const; /// hasUnparsedDefaultArg - Determines whether this parameter has a /// default argument that has not yet been parsed. This will occur @@ -1451,11 +1408,11 @@ public: /// }; // x has a regular default argument now /// @endcode bool hasUnparsedDefaultArg() const { - return Init.is<UnparsedDefaultArgument*>(); + return ParmVarDeclBits.DefaultArgKind == DAK_Unparsed; } bool hasUninstantiatedDefaultArg() const { - return Init.is<UninstantiatedDefaultArgument*>(); + return ParmVarDeclBits.DefaultArgKind == DAK_Uninstantiated; } /// setUnparsedDefaultArg - Specify that this parameter has an @@ -1463,7 +1420,9 @@ public: /// real default argument via setDefaultArg when the class /// definition enclosing the function declaration that owns this /// default argument is completed. - void setUnparsedDefaultArg() { Init = (UnparsedDefaultArgument *)nullptr; } + void setUnparsedDefaultArg() { + ParmVarDeclBits.DefaultArgKind = DAK_Unparsed; + } bool hasInheritedDefaultArg() const { return ParmVarDeclBits.HasInheritedDefaultArg; @@ -1546,25 +1505,25 @@ private: LazyDeclStmtPtr Body; - // FIXME: This can be packed into the bitfields in Decl. - // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum + // FIXME: This can be packed into the bitfields in DeclContext. + // NOTE: VC++ packs bitfields poorly if the types differ. unsigned SClass : 2; - bool IsInline : 1; - bool IsInlineSpecified : 1; - bool IsVirtualAsWritten : 1; - bool IsPure : 1; - bool HasInheritedPrototype : 1; - bool HasWrittenPrototype : 1; - bool IsDeleted : 1; - bool IsTrivial : 1; // sunk from CXXMethodDecl - bool IsDefaulted : 1; // sunk from CXXMethoDecl - bool IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl - bool HasImplicitReturnZero : 1; - bool IsLateTemplateParsed : 1; - bool IsConstexpr : 1; + unsigned IsInline : 1; + unsigned IsInlineSpecified : 1; + unsigned IsVirtualAsWritten : 1; + unsigned IsPure : 1; + unsigned HasInheritedPrototype : 1; + unsigned HasWrittenPrototype : 1; + unsigned IsDeleted : 1; + unsigned IsTrivial : 1; // sunk from CXXMethodDecl + unsigned IsDefaulted : 1; // sunk from CXXMethoDecl + unsigned IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl + unsigned HasImplicitReturnZero : 1; + unsigned IsLateTemplateParsed : 1; + unsigned IsConstexpr : 1; /// \brief Indicates if the function uses __try. - bool UsesSEHTry : 1; + unsigned UsesSEHTry : 1; /// \brief Indicates if the function was a definition but its body was /// skipped. @@ -1835,7 +1794,7 @@ public: bool isConstexpr() const { return IsConstexpr; } void setConstexpr(bool IC) { IsConstexpr = IC; } - /// Whether this is a (C++11) constexpr function or constexpr constructor. + /// \brief Indicates the function uses __try. bool usesSEHTry() const { return UsesSEHTry; } void setUsesSEHTry(bool UST) { UsesSEHTry = UST; } @@ -2084,9 +2043,7 @@ public: /// \brief If this function is an instantiation of a member function of a /// class template specialization, retrieves the member specialization /// information. - MemberSpecializationInfo *getMemberSpecializationInfo() const { - return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>(); - } + MemberSpecializationInfo *getMemberSpecializationInfo() const; /// \brief Specify that this record is an instantiation of the /// member function FD. @@ -2107,13 +2064,9 @@ public: /// FunctionDecl that describes the function template, /// getDescribedFunctionTemplate() retrieves the /// FunctionTemplateDecl from a FunctionDecl. - FunctionTemplateDecl *getDescribedFunctionTemplate() const { - return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl*>(); - } + FunctionTemplateDecl *getDescribedFunctionTemplate() const; - void setDescribedFunctionTemplate(FunctionTemplateDecl *Template) { - TemplateOrSpecialization = Template; - } + void setDescribedFunctionTemplate(FunctionTemplateDecl *Template); /// \brief Determine whether this function is a function template /// specialization. @@ -2128,10 +2081,7 @@ public: /// \brief If this function is actually a function template specialization, /// retrieve information about this function template specialization. /// Otherwise, returns NULL. - FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const { - return TemplateOrSpecialization. - dyn_cast<FunctionTemplateSpecializationInfo*>(); - } + FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const; /// \brief Determines whether this function is a function template /// specialization or a member of a class template specialization that can @@ -2208,10 +2158,7 @@ public: const TemplateArgumentListInfo &TemplateArgs); DependentFunctionTemplateSpecializationInfo * - getDependentSpecializationInfo() const { - return TemplateOrSpecialization. - dyn_cast<DependentFunctionTemplateSpecializationInfo*>(); - } + getDependentSpecializationInfo() const; /// \brief Determine what kind of template instantiation this function /// represents. @@ -2487,7 +2434,8 @@ public: /// IndirectFieldDecl - An instance of this class is created to represent a /// field injected from an anonymous union/struct into the parent scope. /// IndirectFieldDecl are always implicit. -class IndirectFieldDecl : public ValueDecl { +class IndirectFieldDecl : public ValueDecl, + public Mergeable<IndirectFieldDecl> { void anchor() override; NamedDecl **Chaining; unsigned ChainingSize; @@ -2525,6 +2473,9 @@ public: return dyn_cast<VarDecl>(*chain_begin()); } + IndirectFieldDecl *getCanonicalDecl() override { return getFirstDecl(); } + const IndirectFieldDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == IndirectField; } @@ -2762,12 +2713,12 @@ private: /// declaration specifier for variables, it points to the first VarDecl (used /// for mangling); /// otherwise, it is a null (TypedefNameDecl) pointer. - llvm::PointerUnion<NamedDecl *, ExtInfo *> NamedDeclOrQualifier; + llvm::PointerUnion<TypedefNameDecl *, ExtInfo *> TypedefNameDeclOrQualifier; - bool hasExtInfo() const { return NamedDeclOrQualifier.is<ExtInfo *>(); } - ExtInfo *getExtInfo() { return NamedDeclOrQualifier.get<ExtInfo *>(); } + bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo *>(); } + ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo *>(); } const ExtInfo *getExtInfo() const { - return NamedDeclOrQualifier.get<ExtInfo *>(); + return TypedefNameDeclOrQualifier.get<ExtInfo *>(); } protected: @@ -2778,7 +2729,7 @@ protected: TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false), IsEmbeddedInDeclarator(false), IsFreeStanding(false), IsCompleteDefinitionRequired(false), - NamedDeclOrQualifier((NamedDecl *)nullptr) { + TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) { assert((DK != Enum || TK == TTK_Enum) && "EnumDecl not matched with TTK_Enum"); setPreviousDecl(PrevDecl); @@ -2925,22 +2876,11 @@ public: return (getDeclName() || getTypedefNameForAnonDecl()); } - bool hasDeclaratorForAnonDecl() const { - return dyn_cast_or_null<DeclaratorDecl>( - NamedDeclOrQualifier.get<NamedDecl *>()); - } - DeclaratorDecl *getDeclaratorForAnonDecl() const { - return hasExtInfo() ? nullptr : dyn_cast_or_null<DeclaratorDecl>( - NamedDeclOrQualifier.get<NamedDecl *>()); - } - TypedefNameDecl *getTypedefNameForAnonDecl() const { - return hasExtInfo() ? nullptr : dyn_cast_or_null<TypedefNameDecl>( - NamedDeclOrQualifier.get<NamedDecl *>()); + return hasExtInfo() ? nullptr + : TypedefNameDeclOrQualifier.get<TypedefNameDecl *>(); } - void setDeclaratorForAnonDecl(DeclaratorDecl *DD) { NamedDeclOrQualifier = DD; } - void setTypedefNameForAnonDecl(TypedefNameDecl *TDD); /// \brief Retrieve the nested-name-specifier that qualifies the name of this @@ -2967,8 +2907,8 @@ public: assert(i < getNumTemplateParameterLists()); return getExtInfo()->TemplParamLists[i]; } - void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists, - TemplateParameterList **TPLists); + void setTemplateParameterListsInfo(ASTContext &Context, + ArrayRef<TemplateParameterList *> TPLists); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -3301,7 +3241,14 @@ public: bool hasVolatileMember() const { return HasVolatileMember; } void setHasVolatileMember (bool val) { HasVolatileMember = val; } - + + bool hasLoadedFieldsFromExternalStorage() const { + return LoadedFieldsFromExternalStorage; + } + void setHasLoadedFieldsFromExternalStorage(bool val) { + LoadedFieldsFromExternalStorage = val; + } + /// \brief Determines whether this declaration represents the /// injected class name. /// @@ -3475,7 +3422,7 @@ private: Stmt *Body; TypeSourceInfo *SignatureAsWritten; - Capture *Captures; + const Capture *Captures; unsigned NumCaptures; unsigned ManglingNumber; @@ -3581,10 +3528,8 @@ public: bool capturesVariable(const VarDecl *var) const; - void setCaptures(ASTContext &Context, - const Capture *begin, - const Capture *end, - bool capturesCXXThis); + void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures, + bool CapturesCXXThis); unsigned getBlockManglingNumber() const { return ManglingNumber; @@ -3613,7 +3558,15 @@ public: /// \brief This represents the body of a CapturedStmt, and serves as its /// DeclContext. -class CapturedDecl : public Decl, public DeclContext { +class CapturedDecl final + : public Decl, + public DeclContext, + private llvm::TrailingObjects<CapturedDecl, ImplicitParamDecl *> { +protected: + size_t numTrailingObjects(OverloadToken<ImplicitParamDecl>) { + return NumParams; + } + private: /// \brief The number of parameters to the outlined function. unsigned NumParams; @@ -3622,13 +3575,14 @@ private: /// \brief The body of the outlined function. llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow; - explicit CapturedDecl(DeclContext *DC, unsigned NumParams) - : Decl(Captured, DC, SourceLocation()), DeclContext(Captured), - NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) { } + explicit CapturedDecl(DeclContext *DC, unsigned NumParams); + + ImplicitParamDecl *const *getParams() const { + return getTrailingObjects<ImplicitParamDecl *>(); + } - ImplicitParamDecl **getParams() const { - return reinterpret_cast<ImplicitParamDecl **>( - const_cast<CapturedDecl *>(this) + 1); + ImplicitParamDecl **getParams() { + return getTrailingObjects<ImplicitParamDecl *>(); } public: @@ -3637,11 +3591,11 @@ public: static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID, unsigned NumParams); - Stmt *getBody() const override { return BodyAndNothrow.getPointer(); } - void setBody(Stmt *B) { BodyAndNothrow.setPointer(B); } + Stmt *getBody() const override; + void setBody(Stmt *B); - bool isNothrow() const { return BodyAndNothrow.getInt(); } - void setNothrow(bool Nothrow = true) { BodyAndNothrow.setInt(Nothrow); } + bool isNothrow() const; + void setNothrow(bool Nothrow = true); unsigned getNumParams() const { return NumParams; } @@ -3666,7 +3620,7 @@ public: } unsigned getContextParamPosition() const { return ContextParam; } - typedef ImplicitParamDecl **param_iterator; + typedef ImplicitParamDecl *const *param_iterator; typedef llvm::iterator_range<param_iterator> param_range; /// \brief Retrieve an iterator pointing to the first parameter decl. @@ -3689,6 +3643,7 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; + friend TrailingObjects; }; /// \brief Describes a module import declaration, which makes the contents @@ -3701,7 +3656,8 @@ public: /// /// Import declarations can also be implicitly generated from /// \#include/\#import directives. -class ImportDecl : public Decl { +class ImportDecl final : public Decl, + llvm::TrailingObjects<ImportDecl, SourceLocation> { /// \brief The imported module, along with a bit that indicates whether /// we have source-location information for each identifier in the module /// name. @@ -3717,7 +3673,8 @@ class ImportDecl : public Decl { friend class ASTReader; friend class ASTDeclReader; friend class ASTContext; - + friend TrailingObjects; + ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef<SourceLocation> IdentifierLocs); |