Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -19,8 +19,8 @@ #include "clang/AST/CanonicalType.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/Decl.h" -#include "clang/AST/DeclarationName.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" @@ -30,21 +30,21 @@ #include "clang/AST/Type.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/Linkage.h" -#include "clang/Basic/LLVM.h" #include "clang/Basic/Module.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SanitizerBlacklist.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/XRayFunctionFilter.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" @@ -52,9 +52,10 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/TinyPtrVector.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" @@ -100,7 +101,7 @@ namespace Builtin { - class Context; +class Context; } // end namespace Builtin @@ -108,7 +109,7 @@ namespace comments { - class FullComment; +class FullComment; } // end namespace comments @@ -138,50 +139,50 @@ mutable llvm::FoldingSet MemberPointerTypes; mutable llvm::FoldingSet ConstantArrayTypes; mutable llvm::FoldingSet IncompleteArrayTypes; - mutable std::vector VariableArrayTypes; + mutable std::vector VariableArrayTypes; mutable llvm::FoldingSet DependentSizedArrayTypes; mutable llvm::FoldingSet - DependentSizedExtVectorTypes; + DependentSizedExtVectorTypes; mutable llvm::FoldingSet VectorTypes; mutable llvm::FoldingSet FunctionNoProtoTypes; - mutable llvm::ContextualFoldingSet - FunctionProtoTypes; + mutable llvm::ContextualFoldingSet + FunctionProtoTypes; mutable llvm::FoldingSet DependentTypeOfExprTypes; mutable llvm::FoldingSet DependentDecltypeTypes; mutable llvm::FoldingSet TemplateTypeParmTypes; mutable llvm::FoldingSet ObjCTypeParamTypes; mutable llvm::FoldingSet - SubstTemplateTypeParmTypes; + SubstTemplateTypeParmTypes; mutable llvm::FoldingSet - SubstTemplateTypeParmPackTypes; - mutable llvm::ContextualFoldingSet - TemplateSpecializationTypes; + SubstTemplateTypeParmPackTypes; + mutable llvm::ContextualFoldingSet + TemplateSpecializationTypes; mutable llvm::FoldingSet ParenTypes; mutable llvm::FoldingSet ElaboratedTypes; mutable llvm::FoldingSet DependentNameTypes; mutable llvm::ContextualFoldingSet - DependentTemplateSpecializationTypes; + ASTContext &> + DependentTemplateSpecializationTypes; llvm::FoldingSet PackExpansionTypes; mutable llvm::FoldingSet ObjCObjectTypes; mutable llvm::FoldingSet ObjCObjectPointerTypes; mutable llvm::FoldingSet - DependentUnaryTransformTypes; + DependentUnaryTransformTypes; mutable llvm::FoldingSet AutoTypes; mutable llvm::FoldingSet - DeducedTemplateSpecializationTypes; + DeducedTemplateSpecializationTypes; mutable llvm::FoldingSet AtomicTypes; llvm::FoldingSet AttributedTypes; mutable llvm::FoldingSet PipeTypes; mutable llvm::FoldingSet QualifiedTemplateNames; mutable llvm::FoldingSet DependentTemplateNames; - mutable llvm::FoldingSet - SubstTemplateTemplateParms; + mutable llvm::FoldingSet + SubstTemplateTemplateParms; mutable llvm::ContextualFoldingSet - SubstTemplateTemplateParmPacks; - + ASTContext &> + SubstTemplateTemplateParmPacks; + /// \brief The set of nested name specifiers. /// /// This set is managed by the NestedNameSpecifier class. @@ -192,60 +193,61 @@ /// \brief A cache mapping from RecordDecls to ASTRecordLayouts. /// /// This is lazily created. This is intentionally not serialized. - mutable llvm::DenseMap - ASTRecordLayouts; - mutable llvm::DenseMap - ObjCLayouts; + mutable llvm::DenseMap + ASTRecordLayouts; + mutable llvm::DenseMap + ObjCLayouts; /// \brief A cache from types to size and alignment information. typedef llvm::DenseMap TypeInfoMap; mutable TypeInfoMap MemoizedTypeInfo; /// \brief A cache mapping from CXXRecordDecls to key functions. - llvm::DenseMap KeyFunctions; - + llvm::DenseMap KeyFunctions; + /// \brief Mapping from ObjCContainers to their ObjCImplementations. - llvm::DenseMap ObjCImpls; - + llvm::DenseMap ObjCImpls; + /// \brief Mapping from ObjCMethod to its duplicate declaration in the same /// interface. - llvm::DenseMap ObjCMethodRedecls; + llvm::DenseMap + ObjCMethodRedecls; /// \brief Mapping from __block VarDecls to their copy initialization expr. - llvm::DenseMap BlockVarCopyInits; - + llvm::DenseMap BlockVarCopyInits; + /// \brief Mapping from class scope functions specialization to their /// template patterns. - llvm::DenseMap - ClassScopeSpecializationPattern; + llvm::DenseMap + ClassScopeSpecializationPattern; /// \brief Mapping from materialized temporaries with static storage duration /// that appear in constant initializers to their evaluated values. These are /// allocated in a std::map because their address must be stable. llvm::DenseMap - MaterializedTemporaryValues; + MaterializedTemporaryValues; /// \brief Representation of a "canonical" template template parameter that /// is used in canonical template names. class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode { TemplateTemplateParmDecl *Parm; - + public: - CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm) - : Parm(Parm) { } - + CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm) + : Parm(Parm) {} + TemplateTemplateParmDecl *getParam() const { return Parm; } - + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); } - - static void Profile(llvm::FoldingSetNodeID &ID, + + static void Profile(llvm::FoldingSetNodeID &ID, TemplateTemplateParmDecl *Parm); }; mutable llvm::FoldingSet - CanonTemplateTemplateParms; - + CanonTemplateTemplateParms; + TemplateTemplateParmDecl * - getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const; + getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const; /// \brief The typedef for the __int128_t type. mutable TypedefDecl *Int128Decl; @@ -262,7 +264,7 @@ /// \brief The typedef for the predefined \c id type. mutable TypedefDecl *ObjCIdDecl; - + /// \brief The typedef for the predefined \c SEL type. mutable TypedefDecl *ObjCSelDecl; @@ -271,7 +273,7 @@ /// \brief The typedef for the predefined \c Protocol class in Objective-C. mutable ObjCInterfaceDecl *ObjCProtocolClassDecl; - + /// \brief The typedef for the predefined 'BOOL' type. mutable TypedefDecl *BOOLDecl; @@ -301,12 +303,12 @@ mutable TypedefDecl *CFConstantStringTypeDecl; mutable QualType ObjCSuperType; - + QualType ObjCNSStringType; /// \brief The typedef declaration for the Objective-C "instancetype" type. TypedefDecl *ObjCInstanceTypeDecl; - + /// \brief The type for the C FILE type. TypeDecl *FILEDecl; @@ -338,34 +340,34 @@ /// /// Since so few decls have attrs, we keep them in a hash map instead of /// wasting space in the Decl class. - llvm::DenseMap DeclAttrs; + llvm::DenseMap DeclAttrs; /// \brief A mapping from non-redeclarable declarations in modules that were /// merged with other declarations to the canonical declaration that they were /// merged into. - llvm::DenseMap MergedDecls; + llvm::DenseMap MergedDecls; /// \brief A mapping from a defining declaration to a list of modules (other /// than the owning module of the declaration) that contain merged /// definitions of that entity. - llvm::DenseMap> MergedDefModules; + llvm::DenseMap> MergedDefModules; /// \brief Initializers for a module, in order. Each Decl will be either /// something that has a semantic effect on startup (such as a variable with /// a non-constant initializer), or an ImportDecl (which recursively triggers /// initialization of another module). struct PerModuleInitializers { - llvm::SmallVector Initializers; + llvm::SmallVector Initializers; llvm::SmallVector LazyInitializers; void resolve(ASTContext &Ctx); }; - llvm::DenseMap ModuleInitializers; + llvm::DenseMap ModuleInitializers; public: /// \brief A type synonym for the TemplateOrInstantiation mapping. typedef llvm::PointerUnion - TemplateOrSpecializationInfo; + TemplateOrSpecializationInfo; private: /// \brief A mapping to contain the template or declaration that @@ -399,7 +401,7 @@ /// X::value to the corresponding VarDecl for X::value (within the /// class template X) and will be marked TSK_ImplicitInstantiation. llvm::DenseMap - TemplateOrInstantiation; + TemplateOrInstantiation; /// \brief Keeps track of the declaration from which a using declaration was /// created during instantiation. @@ -426,8 +428,8 @@ /// B to the UnresolvedUsingDecl in B. llvm::DenseMap InstantiatedFromUsingDecl; - llvm::DenseMap - InstantiatedFromUsingShadowDecl; + llvm::DenseMap + InstantiatedFromUsingShadowDecl; llvm::DenseMap InstantiatedFromUnnamedFieldDecl; @@ -437,7 +439,7 @@ /// Since most C++ member functions aren't virtual and therefore /// don't override anything, we store the overridden functions in /// this map on the side rather than within the CXXMethodDecl structure. - typedef llvm::TinyPtrVector CXXMethodVector; + typedef llvm::TinyPtrVector CXXMethodVector; llvm::DenseMap OverriddenMethods; /// \brief Mapping from each declaration context to its corresponding @@ -454,11 +456,11 @@ /// \brief Mapping that stores parameterIndex values for ParmVarDecls when /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex. typedef llvm::DenseMap ParameterIndexTable; - ParameterIndexTable ParamIndices; - + ParameterIndexTable ParamIndices; + ImportDecl *FirstLocalImport; ImportDecl *LastLocalImport; - + TranslationUnitDecl *TUDecl; mutable ExternCContextDecl *ExternCContext; mutable BuiltinTemplateDecl *MakeIntegerSeqDecl; @@ -475,6 +477,10 @@ /// entities should not be instrumented. std::unique_ptr SanitizerBL; + //// \brief Function filtering mechanism to determine whether a given + /// function should be imbuued with the XRay "always" or "never" attributes. + std::unique_ptr XRayFilter; + /// \brief The allocator used to create AST objects. /// /// AST objects are never destructed; rather, all memory associated with the @@ -491,7 +497,7 @@ /// \brief The logical -> physical address space map. const LangAS::Map *AddrSpaceMap; - /// \brief Address space map mangling must be used with language specific + /// \brief Address space map mangling must be used with language specific /// address spaces (e.g. OpenCL/CUDA) bool AddrSpaceMapMangling; @@ -503,7 +509,7 @@ const TargetInfo *Target; const TargetInfo *AuxTarget; clang::PrintingPolicy PrintingPolicy; - + public: IdentifierTable &Idents; SelectorTable &Selectors; @@ -518,10 +524,11 @@ /// \brief Maps from a node to its parents. This is used for nodes that have /// pointer identity only, which are more common and we can save space by /// only storing a unique pointer to them. - typedef llvm::DenseMap> ParentMapPointers; + typedef llvm::DenseMap< + const void *, + llvm::PointerUnion4> + ParentMapPointers; /// Parent map for nodes without pointer identity. We store a full /// DynTypedNode for all keys. @@ -536,7 +543,8 @@ class DynTypedNodeList { typedef ast_type_traits::DynTypedNode DynTypedNode; llvm::AlignedCharArrayUnion> Storage; + ArrayRef> + Storage; bool IsSingleNode; public: @@ -607,13 +615,11 @@ void setPrintingPolicy(const clang::PrintingPolicy &Policy) { PrintingPolicy = Policy; } - - SourceManager& getSourceManager() { return SourceMgr; } - const SourceManager& getSourceManager() const { return SourceMgr; } - llvm::BumpPtrAllocator &getAllocator() const { - return BumpAlloc; - } + SourceManager &getSourceManager() { return SourceMgr; } + const SourceManager &getSourceManager() const { return SourceMgr; } + + llvm::BumpPtrAllocator &getAllocator() const { return BumpAlloc; } void *Allocate(size_t Size, unsigned Align = 8) const { return BumpAlloc.Allocate(Size, Align); @@ -621,16 +627,14 @@ template T *Allocate(size_t Num = 1) const { return static_cast(Allocate(Num * sizeof(T), alignof(T))); } - void Deallocate(void *Ptr) const { } - + void Deallocate(void *Ptr) const {} + /// Return the total amount of physical memory allocated for representing /// AST nodes and type information. - size_t getASTAllocatedMemory() const { - return BumpAlloc.getTotalMemory(); - } + size_t getASTAllocatedMemory() const { return BumpAlloc.getTotalMemory(); } /// Return the total memory used for various side tables. size_t getSideTableAllocatedMemory() const; - + PartialDiagnostic::StorageAllocator &getDiagAllocator() { return DiagAllocator; } @@ -642,25 +646,28 @@ /// sets integer QualTy according to specified details: /// bitwidth, signed/unsigned. /// Returns empty type if there is no appropriate target types. - QualType getIntTypeForBitwidth(unsigned DestWidth, - unsigned Signed) const; + QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const; /// getRealTypeForBitwidth - /// sets floating point QualTy according to specified bitwidth. /// Returns empty type if there is no appropriate target types. QualType getRealTypeForBitwidth(unsigned DestWidth) const; bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const; - - const LangOptions& getLangOpts() const { return LangOpts; } + + const LangOptions &getLangOpts() const { return LangOpts; } const SanitizerBlacklist &getSanitizerBlacklist() const { return *SanitizerBL; } + const XRayFunctionFilter &getXRayFilter() const { + return *XRayFilter; + } + DiagnosticsEngine &getDiagnostics() const; FullSourceLoc getFullLoc(SourceLocation Loc) const { - return FullSourceLoc(Loc,SourceMgr); + return FullSourceLoc(Loc, SourceMgr); } /// \brief All comments in this translation unit. @@ -694,29 +701,17 @@ FromRedecl }; - Kind getKind() const LLVM_READONLY { - return Data.getInt(); - } + Kind getKind() const LLVM_READONLY { return Data.getInt(); } - void setKind(Kind K) { - Data.setInt(K); - } + void setKind(Kind K) { Data.setInt(K); } - const RawComment *getRaw() const LLVM_READONLY { - return Data.getPointer(); - } + const RawComment *getRaw() const LLVM_READONLY { return Data.getPointer(); } - void setRaw(const RawComment *RC) { - Data.setPointer(RC); - } + void setRaw(const RawComment *RC) { Data.setPointer(RC); } - const Decl *getOriginalDecl() const LLVM_READONLY { - return OriginalDecl; - } + const Decl *getOriginalDecl() const LLVM_READONLY { return OriginalDecl; } - void setOriginalDecl(const Decl *Orig) { - OriginalDecl = Orig; - } + void setOriginalDecl(const Decl *Orig) { OriginalDecl = Orig; } private: llvm::PointerIntPair Data; @@ -739,9 +734,7 @@ RawComment *getRawCommentForDeclNoCache(const Decl *D) const; public: - RawCommentList &getRawCommentList() { - return Comments; - } + RawCommentList &getRawCommentList() { return Comments; } void addComment(const RawComment &RC) { assert(LangOpts.RetainCommentsFromSystemHeaders || @@ -772,7 +765,7 @@ comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const; comments::FullComment *cloneFullComment(comments::FullComment *FC, - const Decl *D) const; + const Decl *D) const; private: mutable comments::CommandTraits CommentCommandTraits; @@ -782,10 +775,10 @@ ImportDecl *Import; public: - typedef ImportDecl *value_type; - typedef ImportDecl *reference; - typedef ImportDecl *pointer; - typedef int difference_type; + typedef ImportDecl *value_type; + typedef ImportDecl *reference; + typedef ImportDecl *pointer; + typedef int difference_type; typedef std::forward_iterator_tag iterator_category; import_iterator() : Import() {} @@ -820,7 +813,7 @@ } /// \brief Retrieve the attributes for the given declaration. - AttrVec& getDeclAttrs(const Decl *D); + AttrVec &getDeclAttrs(const Decl *D); /// \brief Erase the attributes corresponding to the given declaration. void eraseDeclAttrs(const Decl *D); @@ -829,8 +822,8 @@ /// class template specialization, returns the templated static data member /// from which it was instantiated. // FIXME: Remove ? - MemberSpecializationInfo *getInstantiatedFromStaticDataMember( - const VarDecl *Var); + MemberSpecializationInfo * + getInstantiatedFromStaticDataMember(const VarDecl *Var); TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var); @@ -842,9 +835,9 @@ /// \brief Note that the static data member \p Inst is an instantiation of /// the static data member template \p Tmpl of a class template. - void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl, - TemplateSpecializationKind TSK, - SourceLocation PointOfInstantiation = SourceLocation()); + void setInstantiatedFromStaticDataMember( + VarDecl *Inst, VarDecl *Tmpl, TemplateSpecializationKind TSK, + SourceLocation PointOfInstantiation = SourceLocation()); void setTemplateOrSpecializationInfo(VarDecl *Inst, TemplateOrSpecializationInfo TSI); @@ -865,7 +858,7 @@ FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field); void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl); - + // Access to the set of methods overridden by the given C++ method. typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator; overridden_cxx_method_iterator @@ -881,7 +874,7 @@ /// \brief Note that the given C++ \p Method overrides the given \p /// Overridden method. - void addOverriddenMethod(const CXXMethodDecl *Method, + void addOverriddenMethod(const CXXMethodDecl *Method, const CXXMethodDecl *Overridden); /// \brief Return C++ or ObjC overridden methods for the given \p Method. @@ -891,10 +884,10 @@ /// the same selector and is of the same kind (class or instance). /// A method in an implementation is not considered as overriding the same /// method in the interface or its categories. - void getOverriddenMethods( - const NamedDecl *Method, - SmallVectorImpl &Overridden) const; - + void + getOverriddenMethods(const NamedDecl *Method, + SmallVectorImpl &Overridden) const; + /// \brief Notify the AST context that a new import declaration has been /// parsed or implicitly created within this translation unit. void addedLocalImportDecl(ImportDecl *Import); @@ -902,7 +895,7 @@ static ImportDecl *getNextLocalImport(ImportDecl *Import) { return Import->NextLocalImport; } - + typedef llvm::iterator_range import_range; import_range local_imports() const { return import_range(import_iterator(FirstLocalImport), import_iterator()); @@ -926,7 +919,7 @@ /// \brief Get the additional modules in which the definition \p Def has /// been merged. - ArrayRef getModulesWithMergedDefinition(NamedDecl *Def) { + ArrayRef getModulesWithMergedDefinition(NamedDecl *Def) { auto MergedIt = MergedDefModules.find(Def); if (MergedIt == MergedDefModules.end()) return None; @@ -942,7 +935,7 @@ void addLazyModuleInitializers(Module *M, ArrayRef IDs); /// Get the initializations to perform when importing a module, if any. - ArrayRef getModuleInitializers(Module *M); + ArrayRef getModuleInitializers(Module *M); TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } @@ -954,9 +947,10 @@ CanQualType VoidTy; CanQualType BoolTy; CanQualType CharTy; - CanQualType WCharTy; // [C++ 3.9.1p5]. + CanQualType WCharTy; // [C++ 3.9.1p5]. CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99. - CanQualType WIntTy; // [C99 7.24.1], integer type unchanged by default promotions. + CanQualType + WIntTy; // [C99 7.24.1], integer type unchanged by default promotions. CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99. CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99. CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty; @@ -972,7 +966,7 @@ CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; CanQualType ObjCBuiltinBoolTy; -#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ CanQualType SingletonId; #include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; @@ -1002,9 +996,7 @@ /// \brief Retrieve a pointer to the external AST source associated /// with this AST context, if any. - ExternalASTSource *getExternalSource() const { - return ExternalSource.get(); - } + ExternalASTSource *getExternalSource() const { return ExternalSource.get(); } /// \brief Attach an AST mutation listener to the AST context. /// @@ -1020,7 +1012,7 @@ ASTMutationListener *getASTMutationListener() const { return Listener; } void PrintStats() const; - const SmallVectorImpl& getTypes() const { return Types; } + const SmallVectorImpl &getTypes() const { return Types; } BuiltinTemplateDecl *buildBuiltinTemplateDecl(BuiltinTemplateKind BTK, const IdentifierInfo *II) const; @@ -1065,8 +1057,9 @@ /// qualifiers on ObjCObjectPointerType. It can be set to true when /// contructing the canonical type of a Objective-C type parameter. QualType applyObjCProtocolQualifiers(QualType type, - ArrayRef protocols, bool &hasError, - bool allowOnPointerType = false) const; + ArrayRef protocols, + bool &hasError, + bool allowOnPointerType = false) const; /// \brief Return the uniqued reference to the type for an Objective-C /// gc-qualified type. @@ -1126,14 +1119,14 @@ /// number with the specified element type. QualType getComplexType(QualType T) const; CanQualType getComplexType(CanQualType T) const { - return CanQualType::CreateUnsafe(getComplexType((QualType) T)); + return CanQualType::CreateUnsafe(getComplexType((QualType)T)); } /// \brief Return the uniqued reference to the type for a pointer to /// the specified type. QualType getPointerType(QualType T) const; CanQualType getPointerType(CanQualType T) const { - return CanQualType::CreateUnsafe(getPointerType((QualType) T)); + return CanQualType::CreateUnsafe(getPointerType((QualType)T)); } /// \brief Return the uniqued reference to a type adjusted from the original @@ -1149,7 +1142,7 @@ /// pointer types. QualType getDecayedType(QualType T) const; CanQualType getDecayedType(CanQualType T) const { - return CanQualType::CreateUnsafe(getDecayedType((QualType) T)); + return CanQualType::CreateUnsafe(getDecayedType((QualType)T)); } /// \brief Return the uniqued reference to the atomic type for the specified @@ -1176,25 +1169,23 @@ void setcudaConfigureCallDecl(FunctionDecl *FD) { cudaConfigureCallDecl = FD; } - FunctionDecl *getcudaConfigureCallDecl() { - return cudaConfigureCallDecl; - } + FunctionDecl *getcudaConfigureCallDecl() { return cudaConfigureCallDecl; } /// Returns true iff we need copy/dispose helpers for the given type. bool BlockRequiresCopying(QualType Ty, const VarDecl *D); - - - /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set - /// to false in this case. If HasByrefExtendedLayout returns true, byref variable - /// has extended lifetime. - bool getByrefLifetime(QualType Ty, - Qualifiers::ObjCLifetime &Lifetime, + + /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout + /// is set + /// to false in this case. If HasByrefExtendedLayout returns true, byref + /// variable + /// has extended lifetime. + bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const; - + /// \brief Return the uniqued reference to the type for an lvalue reference /// to the specified type. - QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true) - const; + QualType getLValueReferenceType(QualType T, + bool SpelledAsLValue = true) const; /// \brief Return the uniqued reference to the type for an rvalue reference /// to the specified type. @@ -1234,7 +1225,7 @@ QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const; - + /// \brief Returns a vla type where known sizes are replaced with [*]. QualType getVariableArrayDecayedType(QualType Ty) const; @@ -1256,8 +1247,7 @@ /// /// FIXME: We will need these to be uniqued, or at least comparable, at some /// point. - QualType getDependentSizedExtVectorType(QualType VectorType, - Expr *SizeExpr, + QualType getDependentSizedExtVectorType(QualType VectorType, Expr *SizeExpr, SourceLocation AttrLoc) const; /// \brief Return a K&R style C function type like 'int()'. @@ -1286,7 +1276,8 @@ QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl = nullptr) const { assert(Decl && "Passed null for Decl param"); - if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); + if (Decl->TypeForDecl) + return QualType(Decl->TypeForDecl, 0); if (PrevDecl) { assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl"); @@ -1309,18 +1300,16 @@ QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const; QualType getAttributedType(AttributedType::Kind attrKind, - QualType modifiedType, - QualType equivalentType); + QualType modifiedType, QualType equivalentType); QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced, QualType Replacement) const; - QualType getSubstTemplateTypeParmPackType( - const TemplateTypeParmType *Replaced, - const TemplateArgument &ArgPack); + QualType + getSubstTemplateTypeParmPackType(const TemplateTypeParmType *Replaced, + const TemplateArgument &ArgPack); QualType - getTemplateTypeParmType(unsigned Depth, unsigned Index, - bool ParameterPack, + getTemplateTypeParmType(unsigned Depth, unsigned Index, bool ParameterPack, TemplateTypeParmDecl *ParmDecl = nullptr) const; QualType getTemplateSpecializationType(TemplateName T, @@ -1350,10 +1339,9 @@ const IdentifierInfo *Name, QualType Canon = QualType()) const; - QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, - NestedNameSpecifier *NNS, - const IdentifierInfo *Name, - const TemplateArgumentListInfo &Args) const; + QualType getDependentTemplateSpecializationType( + ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, + const IdentifierInfo *Name, const TemplateArgumentListInfo &Args) const; QualType getDependentTemplateSpecializationType( ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, ArrayRef Args) const; @@ -1373,19 +1361,17 @@ ObjCInterfaceDecl *PrevDecl = nullptr) const; /// Legacy interface: cannot provide type arguments or __kindof. - QualType getObjCObjectType(QualType Base, - ObjCProtocolDecl * const *Protocols, + QualType getObjCObjectType(QualType Base, ObjCProtocolDecl *const *Protocols, unsigned NumProtocols) const; - QualType getObjCObjectType(QualType Base, - ArrayRef typeArgs, + QualType getObjCObjectType(QualType Base, ArrayRef typeArgs, ArrayRef protocols, bool isKindOf) const; QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl, ArrayRef protocols, QualType Canonical = QualType()) const; - + bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl); /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in /// QT's qualified-id protocol list adopt all protocols in IDecl's list @@ -1481,11 +1467,11 @@ /// \brief Return the C structure type used to represent constant CFStrings. QualType getCFConstantStringType() const; - + /// \brief Returns the C struct type for objc_super QualType getObjCSuperType() const; void setObjCSuperType(QualType ST) { ObjCSuperType = ST; } - + /// Get the structure type used to representation CFStrings, or NULL /// if it hasn't yet been built. QualType getRawCFConstantStringType() const { @@ -1503,14 +1489,10 @@ return ObjCConstantStringType; } - QualType getObjCNSStringType() const { - return ObjCNSStringType; - } - - void setObjCNSStringType(QualType T) { - ObjCNSStringType = T; - } - + QualType getObjCNSStringType() const { return ObjCNSStringType; } + + void setObjCNSStringType(QualType T) { ObjCNSStringType = T; } + /// \brief Retrieve the type that \c id has been defined to, which may be /// different from the built-in \c id if \c id has been typedef'd. QualType getObjCIdRedefinitionType() const { @@ -1518,7 +1500,7 @@ return getObjCIdType(); return ObjCIdRedefinitionType; } - + /// \brief Set the user-written type that redefines \c id. void setObjCIdRedefinitionType(QualType RedefType) { ObjCIdRedefinitionType = RedefType; @@ -1531,7 +1513,7 @@ return getObjCClassType(); return ObjCClassRedefinitionType; } - + /// \brief Set the user-written type that redefines 'SEL'. void setObjCClassRedefinitionType(QualType RedefType) { ObjCClassRedefinitionType = RedefType; @@ -1544,7 +1526,7 @@ return getObjCSelType(); return ObjCSelRedefinitionType; } - + /// \brief Set the user-written type that redefines 'SEL'. void setObjCSelRedefinitionType(QualType RedefType) { ObjCSelRedefinitionType = RedefType; @@ -1596,7 +1578,7 @@ /// \brief Retrieve the typedef declaration corresponding to the Objective-C /// "instancetype" type. TypedefDecl *getObjCInstanceTypeDecl(); - + /// \brief Set the type for the C FILE type. void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; } @@ -1653,8 +1635,8 @@ /// /// If \p Field is specified then record field names are also encoded. void getObjCEncodingForType(QualType T, std::string &S, - const FieldDecl *Field=nullptr, - QualType *NotEncodedT=nullptr) const; + const FieldDecl *Field = nullptr, + QualType *NotEncodedT = nullptr) const; /// \brief Emit the Objective-C property type encoding for the given /// type \p T into \p S. @@ -1681,7 +1663,7 @@ /// \brief Return the encoded type for this block declaration. std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const; - + /// getObjCEncodingForPropertyDecl - Return the encoded type for /// this method declaration. If non-NULL, Container must be either /// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should @@ -1691,10 +1673,10 @@ bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, ObjCProtocolDecl *rProto) const; - - ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl( - const ObjCPropertyDecl *PD, - const Decl *Container) const; + + ObjCPropertyImplDecl * + getObjCPropertyImplDeclForPropertyDecl(const ObjCPropertyDecl *PD, + const Decl *Container) const; /// \brief Return the size of type \p T for Objective-C encoding purpose, /// in characters. @@ -1703,61 +1685,51 @@ /// \brief Retrieve the typedef corresponding to the predefined \c id type /// in Objective-C. TypedefDecl *getObjCIdDecl() const; - + /// \brief Represents the Objective-CC \c id type. /// /// This is set up lazily, by Sema. \c id is always a (typedef for a) /// pointer type, a pointer to a struct. - QualType getObjCIdType() const { - return getTypeDeclType(getObjCIdDecl()); - } + QualType getObjCIdType() const { return getTypeDeclType(getObjCIdDecl()); } /// \brief Retrieve the typedef corresponding to the predefined 'SEL' type /// in Objective-C. TypedefDecl *getObjCSelDecl() const; - + /// \brief Retrieve the type that corresponds to the predefined Objective-C /// 'SEL' type. - QualType getObjCSelType() const { - return getTypeDeclType(getObjCSelDecl()); - } + QualType getObjCSelType() const { return getTypeDeclType(getObjCSelDecl()); } /// \brief Retrieve the typedef declaration corresponding to the predefined /// Objective-C 'Class' type. TypedefDecl *getObjCClassDecl() const; - + /// \brief Represents the Objective-C \c Class type. /// /// This is set up lazily, by Sema. \c Class is always a (typedef for a) /// pointer type, a pointer to a struct. - QualType getObjCClassType() const { + QualType getObjCClassType() const { return getTypeDeclType(getObjCClassDecl()); } - /// \brief Retrieve the Objective-C class declaration corresponding to + /// \brief Retrieve the Objective-C class declaration corresponding to /// the predefined \c Protocol class. ObjCInterfaceDecl *getObjCProtocolDecl() const; /// \brief Retrieve declaration of 'BOOL' typedef - TypedefDecl *getBOOLDecl() const { - return BOOLDecl; - } + TypedefDecl *getBOOLDecl() const { return BOOLDecl; } /// \brief Save declaration of 'BOOL' typedef - void setBOOLDecl(TypedefDecl *TD) { - BOOLDecl = TD; - } + void setBOOLDecl(TypedefDecl *TD) { BOOLDecl = TD; } /// \brief type of 'BOOL' type. - QualType getBOOLType() const { - return getTypeDeclType(getBOOLDecl()); - } - + QualType getBOOLType() const { return getTypeDeclType(getBOOLDecl()); } + /// \brief Retrieve the type of the Objective-C \c Protocol class. QualType getObjCProtoType() const { return getObjCInterfaceType(getObjCProtocolDecl()); } - + /// \brief Retrieve the C type declaration corresponding to the predefined /// \c __builtin_va_list type. TypedefDecl *getBuiltinVaListDecl() const; @@ -1820,7 +1792,7 @@ qs.addObjCLifetime(lifetime); return getQualifiedType(type, qs); } - + /// getUnqualifiedObjCPointerType - Returns version of /// Objective-C pointer type with lifetime qualifier removed. QualType getUnqualifiedObjCPointerType(QualType type) const { @@ -1831,7 +1803,7 @@ Qs.removeObjCLifetime(); return getQualifiedType(type.getUnqualifiedType(), Qs); } - + DeclarationNameInfo getNameForTemplate(TemplateName Name, SourceLocation NameLoc) const; @@ -1848,14 +1820,15 @@ OverloadedOperatorKind Operator) const; TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param, TemplateName replacement) const; - TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param, - const TemplateArgument &ArgPack) const; - + TemplateName + getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param, + const TemplateArgument &ArgPack) const; + enum GetBuiltinTypeError { - GE_None, ///< No error - GE_Missing_stdio, ///< Missing a type from - GE_Missing_setjmp, ///< Missing a type from - GE_Missing_ucontext ///< Missing a type from + GE_None, ///< No error + GE_Missing_stdio, ///< Missing a type from + GE_Missing_setjmp, ///< Missing a type from + GE_Missing_ucontext ///< Missing a type from }; /// \brief Return the type for the specified builtin. @@ -1912,10 +1885,8 @@ uint64_t getTypeSize(const Type *T) const { return getTypeInfo(T).Width; } /// \brief Return the size of the character type, in bits. - uint64_t getCharWidth() const { - return getTypeSize(CharTy); - } - + uint64_t getCharWidth() const { return getTypeSize(CharTy); } + /// \brief Convert a size in bits to a size in characters. CharUnits toCharUnitsFromBits(int64_t BitSize) const; @@ -1937,11 +1908,11 @@ /// example, from alignment attributes). unsigned getTypeAlignIfKnown(QualType T) const; - /// \brief Return the ABI-specified alignment of a (complete) type \p T, in + /// \brief Return the ABI-specified alignment of a (complete) type \p T, in /// characters. CharUnits getTypeAlignInChars(QualType T) const; CharUnits getTypeAlignInChars(const Type *T) const; - + // getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the // type is a record, its data size is returned. std::pair getTypeInfoDataSizeInChars(QualType T) const; @@ -1992,8 +1963,8 @@ /// \brief Get or compute information about the layout of the specified /// Objective-C interface. - const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) - const; + const ASTRecordLayout & + getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const; void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS, bool Simple = false) const; @@ -2046,13 +2017,13 @@ VTableContextBase *getVTableContext(); MangleContext *createMangleContext(); - + void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass, - SmallVectorImpl &Ivars) const; - + SmallVectorImpl &Ivars) const; + unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const; - void CollectInheritedProtocols(const Decl *CDecl, - llvm::SmallPtrSet &Protocols); + void CollectInheritedProtocols( + const Decl *CDecl, llvm::SmallPtrSet &Protocols); //===--------------------------------------------------------------------===// // Type Operators @@ -2125,14 +2096,14 @@ *SubTnullability == NullabilityKind::Unspecified || *SuperTnullability == NullabilityKind::Unspecified) return true; - + if (IsParam) { - // Ok for the superclass method parameter to be "nonnull" and the subclass + // Ok for the superclass method parameter to be "nonnull" and the + // subclass // method parameter to be "nullable" return (*SuperTnullability == NullabilityKind::NonNull && *SubTnullability == NullabilityKind::Nullable); - } - else { + } else { // For the return type, it's okay for the superclass method to specify // "nullable" and the subclass method specify "nonnull" return (*SuperTnullability == NullabilityKind::Nullable && @@ -2144,9 +2115,9 @@ bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl, const ObjCMethodDecl *MethodImp); - + bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2); - + /// \brief Retrieves the "canonical" nested name specifier for a /// given nested name specifier. /// @@ -2200,14 +2171,14 @@ /// \brief Determine whether the given template names refer to the same /// template. bool hasSameTemplateName(TemplateName X, TemplateName Y); - + /// \brief Retrieve the "canonical" template argument. /// /// The canonical template argument is the simplest template argument /// (which may be a type, value, expression, or declaration) that /// expresses the value of the argument. - TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) - const; + TemplateArgument + getCanonicalTemplateArgument(const TemplateArgument &Arg) const; /// Type Query functions. If the type is an instance of the specified class, /// return the Type pointer for the underlying maximally pretty type. This @@ -2223,11 +2194,11 @@ const IncompleteArrayType *getAsIncompleteArrayType(QualType T) const { return dyn_cast_or_null(getAsArrayType(T)); } - const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T) - const { + const DependentSizedArrayType * + getAsDependentSizedArrayType(QualType T) const { return dyn_cast_or_null(getAsArrayType(T)); } - + /// \brief Return the innermost element type of an array type. /// /// For example, will return "int" for int[m][n] @@ -2246,14 +2217,14 @@ /// parameter type used by semantic analysis (C99 6.7.5.3p[7,8], /// C++ [dcl.fct]p3). The adjusted parameter type is returned. QualType getAdjustedParameterType(QualType T) const; - + /// \brief Retrieve the parameter type as adjusted for use in the signature /// of a function, decaying array and function types and removing top-level /// cv-qualifiers. QualType getSignatureParameterType(QualType T) const; - + QualType getExceptionObjectType(QualType T) const; - + /// \brief Return the properly qualified result of decaying the specified /// array type to a pointer. /// @@ -2279,7 +2250,7 @@ /// promotion occurs. QualType isPromotableBitField(Expr *E) const; - /// \brief Return the highest ranked integer type, see C99 6.3.1.8p1. + /// \brief Return the highest ranked integer type, see C99 6.3.1.8p1. /// /// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If /// \p LHS < \p RHS, return -1. @@ -2320,8 +2291,7 @@ uint64_t getTargetNullPointerValue(QualType QT) const; bool addressSpaceMapManglingFor(unsigned AS) const { - return AddrSpaceMapMangling || - AS < LangAS::Offset || + return AddrSpaceMapMangling || AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count; } @@ -2335,57 +2305,51 @@ //===--------------------------------------------------------------------===// /// Compatibility predicates used to check assignment expressions. - bool typesAreCompatible(QualType T1, QualType T2, + bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified = false); // C99 6.2.7p1 - bool propertyTypesAreCompatible(QualType, QualType); - bool typesAreBlockPointerCompatible(QualType, QualType); + bool propertyTypesAreCompatible(QualType, QualType); + bool typesAreBlockPointerCompatible(QualType, QualType); - bool isObjCIdType(QualType T) const { - return T == getObjCIdType(); - } - bool isObjCClassType(QualType T) const { - return T == getObjCClassType(); - } - bool isObjCSelType(QualType T) const { - return T == getObjCSelType(); - } + bool isObjCIdType(QualType T) const { return T == getObjCIdType(); } + bool isObjCClassType(QualType T) const { return T == getObjCClassType(); } + bool isObjCSelType(QualType T) const { return T == getObjCSelType(); } bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS, bool ForCompare); bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS); - + // Check the safety of assignment from LHS to RHS bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT); bool canAssignObjCInterfaces(const ObjCObjectType *LHS, const ObjCObjectType *RHS); - bool canAssignObjCInterfacesInBlockPointer( - const ObjCObjectPointerType *LHSOPT, - const ObjCObjectPointerType *RHSOPT, - bool BlockReturnType); + bool + canAssignObjCInterfacesInBlockPointer(const ObjCObjectPointerType *LHSOPT, + const ObjCObjectPointerType *RHSOPT, + bool BlockReturnType); bool areComparableObjCPointerTypes(QualType LHS, QualType RHS); QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT); bool canBindObjCObjectType(QualType To, QualType From); // Functions for calculating composite types - QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false, + QualType mergeTypes(QualType, QualType, bool OfBlockPointer = false, bool Unqualified = false, bool BlockReturnType = false); - QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, + QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer = false, bool Unqualified = false); QualType mergeFunctionParameterTypes(QualType, QualType, bool OfBlockPointer = false, bool Unqualified = false); QualType mergeTransparentUnionType(QualType, QualType, - bool OfBlockPointer=false, + bool OfBlockPointer = false, bool Unqualified = false); - + QualType mergeObjCGCQualifiers(QualType, QualType); - + bool doFunctionTypesMatchOnExtParameterInfos( - const FunctionProtoType *FromFunctionType, - const FunctionProtoType *ToFunctionType); + const FunctionProtoType *FromFunctionType, + const FunctionProtoType *ToFunctionType); void ResetObjCLayout(const ObjCContainerDecl *CD); @@ -2426,12 +2390,10 @@ ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D); /// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if /// none exists. - ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D); + ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D); /// \brief Return true if there is at least one \@implementation in the TU. - bool AnyObjCImplementation() { - return !ObjCImpls.empty(); - } + bool AnyObjCImplementation() { return !ObjCImpls.empty(); } /// \brief Set the implementation of ObjCInterfaceDecl. void setObjCImplementation(ObjCInterfaceDecl *IFaceD, @@ -2452,12 +2414,12 @@ /// an Objective-C method/property/ivar etc. that is part of an interface, /// otherwise returns null. const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const; - + /// \brief Set the copy inialization expression of a block var decl. - void setBlockVarCopyInits(VarDecl*VD, Expr* Init); + void setBlockVarCopyInits(VarDecl *VD, Expr *Init); /// \brief Get the copy initialization expression of the VarDecl \p VD, or /// NULL if none exists. - Expr *getBlockVarCopyInits(const VarDecl* VD); + Expr *getBlockVarCopyInits(const VarDecl *VD); /// \brief Allocate an uninitialized TypeSourceInfo. /// @@ -2476,22 +2438,21 @@ /// initialized to a given location, which defaults to the empty /// location. TypeSourceInfo * - getTrivialTypeSourceInfo(QualType T, + getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation()) const; - /// \brief Add a deallocation callback that will be invoked when the + /// \brief Add a deallocation callback that will be invoked when the /// ASTContext is destroyed. /// /// \param Callback A callback function that will be invoked on destruction. /// /// \param Data Pointer data that will be provided to the callback function /// when it is called. - void AddDeallocation(void (*Callback)(void*), void *Data); + void AddDeallocation(void (*Callback)(void *), void *Data); /// If T isn't trivially destructible, calls AddDeallocation to register it /// for destruction. - template - void addDestruction(T *Ptr) { + template void addDestruction(T *Ptr) { if (!std::is_trivially_destructible::value) { auto DestroyPtr = [](void *V) { static_cast(V)->~T(); }; AddDeallocation(DestroyPtr, Ptr); @@ -2554,15 +2515,15 @@ /// \brief The number of implicitly-declared default constructors. static unsigned NumImplicitDefaultConstructors; - - /// \brief The number of implicitly-declared default constructors for + + /// \brief The number of implicitly-declared default constructors for /// which declarations were built. static unsigned NumImplicitDefaultConstructorsDeclared; /// \brief The number of implicitly-declared copy constructors. static unsigned NumImplicitCopyConstructors; - - /// \brief The number of implicitly-declared copy constructors for + + /// \brief The number of implicitly-declared copy constructors for /// which declarations were built. static unsigned NumImplicitCopyConstructorsDeclared; @@ -2575,25 +2536,25 @@ /// \brief The number of implicitly-declared copy assignment operators. static unsigned NumImplicitCopyAssignmentOperators; - - /// \brief The number of implicitly-declared copy assignment operators for + + /// \brief The number of implicitly-declared copy assignment operators for /// which declarations were built. static unsigned NumImplicitCopyAssignmentOperatorsDeclared; /// \brief The number of implicitly-declared move assignment operators. static unsigned NumImplicitMoveAssignmentOperators; - - /// \brief The number of implicitly-declared move assignment operators for + + /// \brief The number of implicitly-declared move assignment operators for /// which declarations were built. static unsigned NumImplicitMoveAssignmentOperatorsDeclared; /// \brief The number of implicitly-declared destructors. static unsigned NumImplicitDestructors; - - /// \brief The number of implicitly-declared destructors for which + + /// \brief The number of implicitly-declared destructors for which /// declarations were built. static unsigned NumImplicitDestructorsDeclared; - + public: /// \brief Initialize built-in types. /// @@ -2608,28 +2569,24 @@ void InitBuiltinType(CanQualType &R, BuiltinType::Kind K); // Return the Objective-C type encoding for a given type. - void getObjCEncodingForTypeImpl(QualType t, std::string &S, - bool ExpandPointedToStructures, - bool ExpandStructures, - const FieldDecl *Field, - bool OutermostType = false, - bool EncodingProperty = false, - bool StructField = false, - bool EncodeBlockParameters = false, - bool EncodeClassNames = false, - bool EncodePointerToObjCTypedef = false, - QualType *NotEncodedT=nullptr) const; + void getObjCEncodingForTypeImpl( + QualType t, std::string &S, bool ExpandPointedToStructures, + bool ExpandStructures, const FieldDecl *Field, bool OutermostType = false, + bool EncodingProperty = false, bool StructField = false, + bool EncodeBlockParameters = false, bool EncodeClassNames = false, + bool EncodePointerToObjCTypedef = false, + QualType *NotEncodedT = nullptr) const; // Adds the encoding of the structure's members. void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S, const FieldDecl *Field, bool includeVBases = true, - QualType *NotEncodedT=nullptr) const; + QualType *NotEncodedT = nullptr) const; + public: // Adds the encoding of a method parameter or return type. - void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, - QualType T, std::string& S, - bool Extended) const; + void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, QualType T, + std::string &S, bool Extended) const; /// \brief Returns true if this is an inline-initialized static data member /// which is treated as a definition for MSVC compatibility. @@ -2669,7 +2626,7 @@ // FIXME: This currently contains the set of StoredDeclMaps used // by DeclContext objects. This probably should not be in ASTContext, // but we include it here so that ASTContext can quickly deallocate them. - llvm::PointerIntPair LastSDM; + llvm::PointerIntPair LastSDM; friend class DeclContext; friend class DeclarationNameTable; @@ -2698,30 +2655,28 @@ int SectionFlags; SectionInfo() = default; - SectionInfo(DeclaratorDecl *Decl, - SourceLocation PragmaSectionLocation, + SectionInfo(DeclaratorDecl *Decl, SourceLocation PragmaSectionLocation, int SectionFlags) - : Decl(Decl), - PragmaSectionLocation(PragmaSectionLocation), - SectionFlags(SectionFlags) {} + : Decl(Decl), PragmaSectionLocation(PragmaSectionLocation), + SectionFlags(SectionFlags) {} }; llvm::StringMap SectionInfos; }; /// \brief Utility function for constructing a nullary selector. -static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) { - IdentifierInfo* II = &Ctx.Idents.get(name); +static inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) { + IdentifierInfo *II = &Ctx.Idents.get(name); return Ctx.Selectors.getSelector(0, &II); } /// \brief Utility function for constructing an unary selector. -static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) { - IdentifierInfo* II = &Ctx.Idents.get(name); +static inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) { + IdentifierInfo *II = &Ctx.Idents.get(name); return Ctx.Selectors.getSelector(1, &II); } -} // end namespace clang +} // end namespace clang // operator new and delete aren't allowed inside namespaces. @@ -2790,7 +2745,7 @@ /// @param Alignment The alignment of the allocated memory (if the underlying /// allocator supports it). /// @return The allocated memory. Could be NULL. -inline void *operator new[](size_t Bytes, const clang::ASTContext& C, +inline void *operator new[](size_t Bytes, const clang::ASTContext &C, size_t Alignment = 8) { return C.Allocate(Bytes, Alignment); } @@ -2809,8 +2764,8 @@ template typename clang::LazyGenerationalUpdatePtr::ValueType - clang::LazyGenerationalUpdatePtr::makeValue( - const clang::ASTContext &Ctx, T Value) { +clang::LazyGenerationalUpdatePtr::makeValue( + const clang::ASTContext &Ctx, T Value) { // Note, this is implemented here so that ExternalASTSource.h doesn't need to // include ASTContext.h. We explicitly instantiate it for all relevant types // in ASTContext.cpp. Index: include/clang/Basic/LangOptions.h =================================================================== --- include/clang/Basic/LangOptions.h +++ include/clang/Basic/LangOptions.h @@ -29,16 +29,16 @@ /// this large collection of bitfields is a trivial class type. class LangOptionsBase { public: - // Define simple language options (with no accessors). +// Define simple language options (with no accessors). #define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits; #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) #include "clang/Basic/LangOptions.def" protected: - // Define language options of enumeration type. These are private, and will - // have accessors (below). +// Define language options of enumeration type. These are private, and will +// have accessors (below). #define LANGOPT(Name, Bits, Default, Description) -#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ unsigned Name : Bits; #include "clang/Basic/LangOptions.def" }; @@ -48,14 +48,14 @@ class LangOptions : public LangOptionsBase { public: typedef clang::Visibility Visibility; - + enum GCMode { NonGC, GCOnly, HybridGC }; enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq }; - + enum SignedOverflowBehaviorTy { - SOB_Undefined, // Default C standard behavior. - SOB_Defined, // -fwrapv - SOB_Trapping // -ftrapv + SOB_Undefined, // Default C standard behavior. + SOB_Defined, // -fwrapv + SOB_Trapping // -ftrapv }; enum CompilingModuleKind { @@ -96,10 +96,20 @@ /// (files, functions, variables) should not be instrumented. std::vector SanitizerBlacklistFiles; + /// \breif Paths to the XRay "always instrument" files specifying which + /// objects (files, functions, variables) should be imbued with the XRay + /// "always instrument" attribute. + std::vector XRayAlwaysInstrumentFiles; + + /// \breif Paths to the XRay "never instrument" files specifying which + /// objects (files, functions, variables) should be imbued with the XRay + /// "never instrument" attribute. + std::vector XRayNeverInstrumentFiles; + clang::ObjCRuntime ObjCRuntime; std::string ObjCConstantStringClass; - + /// \brief The name of the handler function to be called when -ftrapv is /// specified. /// @@ -138,22 +148,20 @@ LangOptions(); - // Define accessors/mutators for language options of enumeration type. -#define LANGOPT(Name, Bits, Default, Description) -#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ - Type get##Name() const { return static_cast(Name); } \ - void set##Name(Type Value) { Name = static_cast(Value); } +// Define accessors/mutators for language options of enumeration type. +#define LANGOPT(Name, Bits, Default, Description) +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + Type get##Name() const { return static_cast(Name); } \ + void set##Name(Type Value) { Name = static_cast(Value); } #include "clang/Basic/LangOptions.def" /// Are we compiling a module interface (.cppm or module map)? - bool isCompilingModule() const { - return getCompilingModule() != CMK_None; - } + bool isCompilingModule() const { return getCompilingModule() != CMK_None; } bool isSignedOverflowDefined() const { return getSignedOverflowBehavior() == SOB_Defined; } - + bool isSubscriptPointerArithmetic() const { return ObjCRuntime.isSubscriptPointerArithmetic() && !ObjCSubscriptingLegacyRuntime; @@ -179,8 +187,8 @@ FPOptions() : fp_contract(0) {} - FPOptions(const LangOptions &LangOpts) : - fp_contract(LangOpts.DefaultFPContract) {} + FPOptions(const LangOptions &LangOpts) + : fp_contract(LangOpts.DefaultFPContract) {} }; /// \brief Describes the kind of translation unit being processed. @@ -193,7 +201,7 @@ /// \brief The translation unit is a module. TU_Module }; - -} // end namespace clang + +} // end namespace clang #endif Index: include/clang/Basic/LangOptions.def =================================================================== --- include/clang/Basic/LangOptions.def +++ include/clang/Basic/LangOptions.def @@ -262,6 +262,8 @@ "field padding (0: none, 1:least " "aggressive, 2: more aggressive)") +LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation") + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT Index: include/clang/Basic/XRayFunctionFilter.h =================================================================== --- /dev/null +++ include/clang/Basic/XRayFunctionFilter.h @@ -0,0 +1,54 @@ +//===--- XRayFunctionFilter.h - XRay automatic-attribution ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// User-provided filters for always/never XRay instrumenting certain functions. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_BASIC_XRAYFUNCTIONFILTER_H +#define LLVM_CLANG_BASIC_XRAYFUNCTIONFILTER_H + +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/SpecialCaseList.h" +#include + +namespace clang { + +class XRayFunctionFilter { + std::unique_ptr AlwaysInstrument; + std::unique_ptr NeverInstrument; + SourceManager &SM; + +public: + XRayFunctionFilter(ArrayRef AlwaysInstrumentPaths, + ArrayRef NeverInstrumentPaths, + SourceManager &SM); + + enum class ImbueAttribute { + NONE, + ALWAYS, + NEVER, + }; + + ImbueAttribute shouldImbueFunction(StringRef FunctionName) const; + + ImbueAttribute + shouldImbueFunctionsInFile(StringRef Filename, + StringRef Category = StringRef()) const; + + ImbueAttribute shouldImbueLocation(SourceLocation Loc, + StringRef Category = StringRef()) const; +}; + +} // namespace clang + +#endif Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -954,6 +954,15 @@ JoinedOrSeparate<["-"], "fxray-instruction-threshold">, Group, Flags<[CC1Option]>; +def fxray_always_instrument : + JoinedOrSeparate<["-"], "fxray-always-instrument=">, + Group, Flags<[CC1Option]>, + HelpText<"Filename defining the whitelist for imbuing the 'always instrument' XRay attribute.">; +def fxray_never_instrument : + JoinedOrSeparate<["-"], "fxray-never-instrument=">, + Group, Flags<[CC1Option]>, + HelpText<"Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">; + def flat__namespace : Flag<["-"], "flat_namespace">; def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group; def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group; Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -748,6 +748,8 @@ ExternCContext(nullptr), MakeIntegerSeqDecl(nullptr), TypePackElementDecl(nullptr), SourceMgr(SM), LangOpts(LOpts), SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)), + XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles, + LangOpts.XRayNeverInstrumentFiles, SM)), AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr), PrintingPolicy(LOpts), Idents(idents), Selectors(sels), BuiltinInfo(builtins), DeclarationNames(*this), ExternalSource(nullptr), Index: lib/Basic/CMakeLists.txt =================================================================== --- lib/Basic/CMakeLists.txt +++ lib/Basic/CMakeLists.txt @@ -89,6 +89,7 @@ VersionTuple.cpp VirtualFileSystem.cpp Warnings.cpp + XRayFunctionFilter.cpp ${version_inc} ) Index: lib/Basic/LangOptions.cpp =================================================================== --- lib/Basic/LangOptions.cpp +++ lib/Basic/LangOptions.cpp @@ -15,8 +15,7 @@ using namespace clang; -LangOptions::LangOptions() - : IsHeaderFile(false) { +LangOptions::LangOptions() : IsHeaderFile(false) { #define LANGOPT(Name, Bits, Default, Description) Name = Default; #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default); #include "clang/Basic/LangOptions.def" @@ -25,7 +24,7 @@ void LangOptions::resetNonModularOptions() { #define LANGOPT(Name, Bits, Default, Description) #define BENIGN_LANGOPT(Name, Bits, Default, Description) Name = Default; -#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ +#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ Name = Default; #include "clang/Basic/LangOptions.def" @@ -33,6 +32,8 @@ // sanitizer options (this affects __has_feature(address_sanitizer) etc). Sanitize.clear(); SanitizerBlacklistFiles.clear(); + XRayAlwaysInstrumentFiles.clear(); + XRayNeverInstrumentFiles.clear(); CurrentModule.clear(); IsHeaderFile = false; Index: lib/Basic/XRayFunctionFilter.cpp =================================================================== --- /dev/null +++ lib/Basic/XRayFunctionFilter.cpp @@ -0,0 +1,53 @@ +//===--- XRayFunctionFilter.cpp - XRay automatic-attribution --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// User-provided filters for always/never XRay instrumenting certain functions. +// +//===----------------------------------------------------------------------===// +#include "clang/Basic/XRayFunctionFilter.h" + +using namespace clang; + +XRayFunctionFilter::XRayFunctionFilter( + ArrayRef AlwaysInstrumentPaths, + ArrayRef NeverInstrumentPaths, SourceManager &SM) + : AlwaysInstrument( + llvm::SpecialCaseList::createOrDie(AlwaysInstrumentPaths)), + NeverInstrument(llvm::SpecialCaseList::createOrDie(NeverInstrumentPaths)), + SM(SM) {} + +XRayFunctionFilter::ImbueAttribute +XRayFunctionFilter::shouldImbueFunction(StringRef FunctionName) const { + // First apply the always instrument list, than if it isn't an "always" see + // whether it's treated as a "never" instrument function. + if (AlwaysInstrument->inSection("fun", FunctionName)) + return ImbueAttribute::ALWAYS; + if (NeverInstrument->inSection("fun", FunctionName)) + return ImbueAttribute::NEVER; + return ImbueAttribute::NONE; +} + +XRayFunctionFilter::ImbueAttribute +XRayFunctionFilter::shouldImbueFunctionsInFile(StringRef Filename, + StringRef Category) const { + if (AlwaysInstrument->inSection("src", Filename, Category)) + return ImbueAttribute::ALWAYS; + if (NeverInstrument->inSection("src", Filename, Category)) + return ImbueAttribute::NEVER; + return ImbueAttribute::NONE; +} + +XRayFunctionFilter::ImbueAttribute +XRayFunctionFilter::shouldImbueLocation(SourceLocation Loc, + StringRef Category) const { + if (!Loc.isValid()) + return ImbueAttribute::NONE; + return this->shouldImbueFunctionsInFile(SM.getFilename(SM.getFileLoc(Loc)), + Category); +} Index: lib/CodeGen/CodeGenFunction.cpp =================================================================== --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -780,9 +780,10 @@ if (XRayAttr->neverXRayInstrument()) Fn->addFnAttr("function-instrument", "xray-never"); } else { - Fn->addFnAttr( - "xray-instruction-threshold", - llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold)); + if (!CGM.imbueXRayAttrs(Fn, Loc)) + Fn->addFnAttr( + "xray-instruction-threshold", + llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold)); } } Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -28,6 +28,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/SanitizerBlacklist.h" +#include "clang/Basic/XRayFunctionFilter.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -1126,6 +1127,12 @@ QualType Ty, StringRef Category = StringRef()) const; + /// Imbue XRay attributes to a function, applying the always/never attribute + /// lists in the process. Returns true if we did imbue attributes this way, + /// false otherwise. + bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, + StringRef Category = StringRef()) const; + SanitizerMetadata *getSanitizerMetadata() { return SanitizerMD.get(); } Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -1482,6 +1482,30 @@ return false; } +bool CodeGenModule::imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, + StringRef Category) const { + if (!LangOpts.XRayInstrument) + return false; + const auto &XRayFilter = getContext().getXRayFilter(); + using ImbueAttr = XRayFunctionFilter::ImbueAttribute; + auto Attr = XRayFunctionFilter::ImbueAttribute::NONE; + if (Loc.isValid()) + Attr = XRayFilter.shouldImbueLocation(Loc, Category); + if (Attr == ImbueAttr::NONE) + Attr = XRayFilter.shouldImbueFunction(Fn->getName()); + switch (Attr) { + case ImbueAttr::NONE: + return false; + case ImbueAttr::ALWAYS: + Fn->addFnAttr("function-instrument", "xray-always"); + break; + case ImbueAttr::NEVER: + Fn->addFnAttr("function-instrument", "xray-never"); + break; + } + return true; +} + bool CodeGenModule::MustBeEmitted(const ValueDecl *Global) { // Never defer when EmitAllDecls is specified. if (LangOpts.EmitAllDecls) Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2281,6 +2281,14 @@ Opts.SanitizeAddressFieldPadding = getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags); Opts.SanitizerBlacklistFiles = Args.getAllArgValues(OPT_fsanitize_blacklist); + + // -fxray-{always,never}-instrument= filenames. + Opts.XRayInstrument = + Args.hasFlag(OPT_fxray_instrument, OPT_fnoxray_instrument, false); + Opts.XRayAlwaysInstrumentFiles = + Args.getAllArgValues(OPT_fxray_always_instrument); + Opts.XRayNeverInstrumentFiles = + Args.getAllArgValues(OPT_fxray_never_instrument); } static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, Index: test/CodeGen/xray-always-instrument.cpp =================================================================== --- /dev/null +++ test/CodeGen/xray-always-instrument.cpp @@ -0,0 +1,15 @@ +// RUN: echo "fun:*foo*" > %t.always-instrument +// RUN: echo "src:*xray-always-instrument.cpp" >> %t.always-instrument +// RUN: %clang_cc1 -fxray-instrument -x c++ -std=c++11 -fxray-always-instrument=%t.always-instrument -emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck %s + +void foo() {} + +[[clang::xray_never_instrument]] void bar() {} + +void baz() {} + +// CHECK: define void @_Z3foov() #[[ALWAYSATTR:[0-9]+]] { +// CHECK: define void @_Z3barv() #[[NEVERATTR:[0-9]+]] { +// CHECK: define void @_Z3bazv() #[[ALWAYSATTR:[0-9]+]] { +// CHECK: attributes #[[ALWAYSATTR]] = {{.*}} "function-instrument"="xray-always" {{.*}} +// CHECK: attributes #[[NEVERATTR]] = {{.*}} "function-instrument"="xray-never" {{.*}}