//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines the ASTContext interface. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_ASTCONTEXT_H #define LLVM_CLANG_AST_ASTCONTEXT_H #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/VersionTuple.h" #include "clang/AST/Decl.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include "clang/AST/CanonicalType.h" #include "clang/AST/UsuallyTinyPtrVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/Allocator.h" #include namespace llvm { struct fltSemantics; } namespace clang { class FileManager; class ASTRecordLayout; class BlockExpr; class CharUnits; class DiagnosticsEngine; class Expr; class ExternalASTSource; class ASTMutationListener; class IdentifierTable; class SelectorTable; class SourceManager; class TargetInfo; class CXXABI; // Decls class DeclContext; class CXXMethodDecl; class CXXRecordDecl; class Decl; class FieldDecl; class MangleContext; class ObjCIvarDecl; class ObjCIvarRefExpr; class ObjCPropertyDecl; class ParmVarDecl; class RecordDecl; class StoredDeclsMap; class TagDecl; class TemplateTemplateParmDecl; class TemplateTypeParmDecl; class TranslationUnitDecl; class TypeDecl; class TypedefNameDecl; class UsingDecl; class UsingShadowDecl; class UnresolvedSetIterator; namespace Builtin { class Context; } /// ASTContext - This class holds long-lived AST nodes (such as types and /// decls) that can be referred to throughout the semantic analysis of a file. class ASTContext : public llvm::RefCountedBase { ASTContext &this_() { return *this; } mutable std::vector Types; mutable llvm::FoldingSet ExtQualNodes; mutable llvm::FoldingSet ComplexTypes; mutable llvm::FoldingSet PointerTypes; mutable llvm::FoldingSet BlockPointerTypes; mutable llvm::FoldingSet LValueReferenceTypes; mutable llvm::FoldingSet RValueReferenceTypes; mutable llvm::FoldingSet MemberPointerTypes; mutable llvm::FoldingSet ConstantArrayTypes; mutable llvm::FoldingSet IncompleteArrayTypes; mutable std::vector VariableArrayTypes; mutable llvm::FoldingSet DependentSizedArrayTypes; mutable llvm::FoldingSet DependentSizedExtVectorTypes; mutable llvm::FoldingSet VectorTypes; mutable llvm::FoldingSet FunctionNoProtoTypes; mutable llvm::ContextualFoldingSet FunctionProtoTypes; mutable llvm::FoldingSet DependentTypeOfExprTypes; mutable llvm::FoldingSet DependentDecltypeTypes; mutable llvm::FoldingSet TemplateTypeParmTypes; mutable llvm::FoldingSet SubstTemplateTypeParmTypes; mutable llvm::FoldingSet SubstTemplateTypeParmPackTypes; mutable llvm::ContextualFoldingSet TemplateSpecializationTypes; mutable llvm::FoldingSet ParenTypes; mutable llvm::FoldingSet ElaboratedTypes; mutable llvm::FoldingSet DependentNameTypes; mutable llvm::ContextualFoldingSet DependentTemplateSpecializationTypes; llvm::FoldingSet PackExpansionTypes; mutable llvm::FoldingSet ObjCObjectTypes; mutable llvm::FoldingSet ObjCObjectPointerTypes; mutable llvm::FoldingSet AutoTypes; mutable llvm::FoldingSet AtomicTypes; llvm::FoldingSet AttributedTypes; mutable llvm::FoldingSet QualifiedTemplateNames; mutable llvm::FoldingSet DependentTemplateNames; mutable llvm::FoldingSet SubstTemplateTemplateParms; mutable llvm::ContextualFoldingSet SubstTemplateTemplateParmPacks; /// \brief The set of nested name specifiers. /// /// This set is managed by the NestedNameSpecifier class. mutable llvm::FoldingSet NestedNameSpecifiers; mutable NestedNameSpecifier *GlobalNestedNameSpecifier; friend class NestedNameSpecifier; /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts. /// This is lazily created. This is intentionally not serialized. mutable llvm::DenseMap ASTRecordLayouts; mutable llvm::DenseMap ObjCLayouts; /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions. llvm::DenseMap KeyFunctions; /// \brief Mapping from ObjCContainers to their ObjCImplementations. llvm::DenseMap ObjCImpls; /// \brief Mapping from ObjCMethod to its duplicate declaration in the same /// interface. llvm::DenseMap ObjCMethodRedecls; /// \brief Mapping from __block VarDecls to their copy initialization expr. llvm::DenseMap BlockVarCopyInits; /// \brief Mapping from class scope functions specialization to their /// template patterns. llvm::DenseMap ClassScopeSpecializationPattern; /// \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) { } TemplateTemplateParmDecl *getParam() const { return Parm; } void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); } static void Profile(llvm::FoldingSetNodeID &ID, TemplateTemplateParmDecl *Parm); }; mutable llvm::FoldingSet CanonTemplateTemplateParms; TemplateTemplateParmDecl * getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const; /// \brief The typedef for the __int128_t type. mutable TypedefDecl *Int128Decl; /// \brief The typedef for the __uint128_t type. mutable TypedefDecl *UInt128Decl; /// BuiltinVaListType - built-in va list type. /// This is initially null and set by Sema::LazilyCreateBuiltin when /// a builtin that takes a valist is encountered. QualType BuiltinVaListType; /// \brief The typedef for the predefined 'id' type. mutable TypedefDecl *ObjCIdDecl; /// \brief The typedef for the predefined 'SEL' type. mutable TypedefDecl *ObjCSelDecl; QualType ObjCProtoType; const RecordType *ProtoStructType; /// \brief The typedef for the predefined 'Class' type. mutable TypedefDecl *ObjCClassDecl; // Typedefs which may be provided defining the structure of Objective-C // pseudo-builtins QualType ObjCIdRedefinitionType; QualType ObjCClassRedefinitionType; QualType ObjCSelRedefinitionType; QualType ObjCConstantStringType; mutable RecordDecl *CFConstantStringTypeDecl; /// \brief The typedef declaration for the Objective-C "instancetype" type. TypedefDecl *ObjCInstanceTypeDecl; /// \brief The type for the C FILE type. TypeDecl *FILEDecl; /// \brief The type for the C jmp_buf type. TypeDecl *jmp_bufDecl; /// \brief The type for the C sigjmp_buf type. TypeDecl *sigjmp_bufDecl; /// \brief Type for the Block descriptor for Blocks CodeGen. /// /// Since this is only used for generation of debug info, it is not /// serialized. mutable RecordDecl *BlockDescriptorType; /// \brief Type for the Block descriptor for Blocks CodeGen. /// /// Since this is only used for generation of debug info, it is not /// serialized. mutable RecordDecl *BlockDescriptorExtendedType; /// \brief Declaration for the CUDA cudaConfigureCall function. FunctionDecl *cudaConfigureCallDecl; TypeSourceInfo NullTypeSourceInfo; /// \brief Keeps track of all declaration attributes. /// /// Since so few decls have attrs, we keep them in a hash map instead of /// wasting space in the Decl class. llvm::DenseMap DeclAttrs; /// \brief Keeps track of the static data member templates from which /// static data members of class template specializations were instantiated. /// /// This data structure stores the mapping from instantiations of static /// data members to the static data member representations within the /// class template from which they were instantiated along with the kind /// of instantiation or specialization (a TemplateSpecializationKind - 1). /// /// Given the following example: /// /// \code /// template /// struct X { /// static T value; /// }; /// /// template /// T X::value = T(17); /// /// int *x = &X::value; /// \endcode /// /// This mapping will contain an entry that maps from the VarDecl for /// X::value to the corresponding VarDecl for X::value (within the /// class template X) and will be marked TSK_ImplicitInstantiation. llvm::DenseMap InstantiatedFromStaticDataMember; /// \brief Keeps track of the declaration from which a UsingDecl was /// created during instantiation. The source declaration is always /// a UsingDecl, an UnresolvedUsingValueDecl, or an /// UnresolvedUsingTypenameDecl. /// /// For example: /// \code /// template /// struct A { /// void f(); /// }; /// /// template /// struct B : A { /// using A::f; /// }; /// /// template struct B; /// \endcode /// /// This mapping will contain an entry that maps from the UsingDecl in /// B to the UnresolvedUsingDecl in B. llvm::DenseMap InstantiatedFromUsingDecl; llvm::DenseMap InstantiatedFromUsingShadowDecl; llvm::DenseMap InstantiatedFromUnnamedFieldDecl; /// \brief Mapping that stores the methods overridden by a given C++ /// member function. /// /// 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 UsuallyTinyPtrVector CXXMethodVector; llvm::DenseMap OverriddenMethods; /// \brief Mapping that stores parameterIndex values for ParmVarDecls /// when that value exceeds the bitfield size of /// ParmVarDeclBits.ParameterIndex. typedef llvm::DenseMap ParameterIndexTable; ParameterIndexTable ParamIndices; TranslationUnitDecl *TUDecl; /// SourceMgr - The associated SourceManager object. SourceManager &SourceMgr; /// LangOpts - The language options used to create the AST associated with /// this ASTContext object. LangOptions &LangOpts; /// \brief The allocator used to create AST objects. /// /// AST objects are never destructed; rather, all memory associated with the /// AST objects will be released when the ASTContext itself is destroyed. mutable llvm::BumpPtrAllocator BumpAlloc; /// \brief Allocator for partial diagnostics. PartialDiagnostic::StorageAllocator DiagAllocator; /// \brief The current C++ ABI. llvm::OwningPtr ABI; CXXABI *createCXXABI(const TargetInfo &T); /// \brief The logical -> physical address space map. const LangAS::Map *AddrSpaceMap; friend class ASTDeclReader; friend class ASTReader; friend class ASTWriter; const TargetInfo *Target; clang::PrintingPolicy PrintingPolicy; public: IdentifierTable &Idents; SelectorTable &Selectors; Builtin::Context &BuiltinInfo; mutable DeclarationNameTable DeclarationNames; llvm::OwningPtr ExternalSource; ASTMutationListener *Listener; clang::PrintingPolicy getPrintingPolicy() const { return PrintingPolicy; } void setPrintingPolicy(clang::PrintingPolicy Policy) { PrintingPolicy = Policy; } SourceManager& getSourceManager() { return SourceMgr; } const SourceManager& getSourceManager() const { return SourceMgr; } void *Allocate(unsigned Size, unsigned Align = 8) const { return BumpAlloc.Allocate(Size, Align); } 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(); } /// Return the total memory used for various side tables. size_t getSideTableAllocatedMemory() const; PartialDiagnostic::StorageAllocator &getDiagAllocator() { return DiagAllocator; } const TargetInfo &getTargetInfo() const { return *Target; } const LangOptions& getLangOptions() const { return LangOpts; } DiagnosticsEngine &getDiagnostics() const; FullSourceLoc getFullLoc(SourceLocation Loc) const { return FullSourceLoc(Loc,SourceMgr); } /// \brief Retrieve the attributes for the given declaration. AttrVec& getDeclAttrs(const Decl *D); /// \brief Erase the attributes corresponding to the given declaration. void eraseDeclAttrs(const Decl *D); /// \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. MemberSpecializationInfo *getInstantiatedFromStaticDataMember( const VarDecl *Var); FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD); void setClassScopeSpecializationPattern(FunctionDecl *FD, FunctionDecl *Pattern); /// \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()); /// \brief If the given using decl is an instantiation of a /// (possibly unresolved) using decl from a template instantiation, /// return it. NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst); /// \brief Remember that the using decl \p Inst is an instantiation /// of the using decl \p Pattern of a class template. void setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern); void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst, UsingShadowDecl *Pattern); UsingShadowDecl *getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst); FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field); void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl); /// ZeroBitfieldFollowsNonBitfield - return 'true" if 'FD' is a zero-length /// bitfield which follows the non-bitfield 'LastFD'. bool ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; /// ZeroBitfieldFollowsBitfield - return 'true" if 'FD' is a zero-length /// bitfield which follows the bitfield 'LastFD'. bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; /// BitfieldFollowsBitfield - return 'true" if 'FD' is a /// bitfield which follows the bitfield 'LastFD'. bool BitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; /// NonBitfieldFollowsBitfield - return 'true" if 'FD' is not a /// bitfield which follows the bitfield 'LastFD'. bool NonBitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; /// BitfieldFollowsNonBitfield - return 'true" if 'FD' is a /// bitfield which follows the none bitfield 'LastFD'. bool BitfieldFollowsNonBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; // Access to the set of methods overridden by the given C++ method. typedef CXXMethodVector::iterator overridden_cxx_method_iterator; overridden_cxx_method_iterator overridden_methods_begin(const CXXMethodDecl *Method) const; overridden_cxx_method_iterator overridden_methods_end(const CXXMethodDecl *Method) const; unsigned overridden_methods_size(const CXXMethodDecl *Method) const; /// \brief Note that the given C++ \p Method overrides the given \p /// Overridden method. void addOverriddenMethod(const CXXMethodDecl *Method, const CXXMethodDecl *Overridden); TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } // Builtin Types. CanQualType VoidTy; CanQualType BoolTy; CanQualType CharTy; CanQualType WCharTy; // [C++ 3.9.1p5], integer type in C99. 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; CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy; CanQualType UnsignedLongLongTy, UnsignedInt128Ty; CanQualType FloatTy, DoubleTy, LongDoubleTy; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; CanQualType VoidPtrTy, NullPtrTy; CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand. mutable QualType AutoDeductTy; // Deduction against 'auto'. mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'. ASTContext(LangOptions& LOpts, SourceManager &SM, const TargetInfo *t, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins, unsigned size_reserve, bool DelayInitialization = false); ~ASTContext(); /// \brief Attach an external AST source to the AST context. /// /// The external AST source provides the ability to load parts of /// the abstract syntax tree as needed from some external storage, /// e.g., a precompiled header. void setExternalSource(llvm::OwningPtr &Source); /// \brief Retrieve a pointer to the external AST source associated /// with this AST context, if any. ExternalASTSource *getExternalSource() const { return ExternalSource.get(); } /// \brief Attach an AST mutation listener to the AST context. /// /// The AST mutation listener provides the ability to track modifications to /// the abstract syntax tree entities committed after they were initially /// created. void setASTMutationListener(ASTMutationListener *Listener) { this->Listener = Listener; } /// \brief Retrieve a pointer to the AST mutation listener associated /// with this AST context, if any. ASTMutationListener *getASTMutationListener() const { return Listener; } void PrintStats() const; const std::vector& getTypes() const { return Types; } /// \brief Retrieve the declaration for the 128-bit signed integer type. TypedefDecl *getInt128Decl() const; /// \brief Retrieve the declaration for the 128-bit unsigned integer type. TypedefDecl *getUInt128Decl() const; //===--------------------------------------------------------------------===// // Type Constructors //===--------------------------------------------------------------------===// private: /// getExtQualType - Return a type with extended qualifiers. QualType getExtQualType(const Type *Base, Qualifiers Quals) const; QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const; public: /// getAddSpaceQualType - Return the uniqued reference to the type for an /// address space qualified type with the specified type and address space. /// The resulting type has a union of the qualifiers from T and the address /// space. If T already has an address space specifier, it is silently /// replaced. QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const; /// getObjCGCQualType - Returns the uniqued reference to the type for an /// objc gc qualified type. The retulting type has a union of the qualifiers /// from T and the gc attribute. QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const; /// getRestrictType - Returns the uniqued reference to the type for a /// 'restrict' qualified type. The resulting type has a union of the /// qualifiers from T and 'restrict'. QualType getRestrictType(QualType T) const { return T.withFastQualifiers(Qualifiers::Restrict); } /// getVolatileType - Returns the uniqued reference to the type for a /// 'volatile' qualified type. The resulting type has a union of the /// qualifiers from T and 'volatile'. QualType getVolatileType(QualType T) const { return T.withFastQualifiers(Qualifiers::Volatile); } /// getConstType - Returns the uniqued reference to the type for a /// 'const' qualified type. The resulting type has a union of the /// qualifiers from T and 'const'. /// /// It can be reasonably expected that this will always be /// equivalent to calling T.withConst(). QualType getConstType(QualType T) const { return T.withConst(); } /// adjustFunctionType - Change the ExtInfo on a function type. const FunctionType *adjustFunctionType(const FunctionType *Fn, FunctionType::ExtInfo EInfo); /// getComplexType - Return the uniqued reference to the type for a complex /// number with the specified element type. QualType getComplexType(QualType T) const; CanQualType getComplexType(CanQualType T) const { return CanQualType::CreateUnsafe(getComplexType((QualType) T)); } /// getPointerType - 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)); } /// getAtomicType - Return the uniqued reference to the atomic type for /// the specified type. QualType getAtomicType(QualType T) const; /// getBlockPointerType - Return the uniqued reference to the type for a block /// of the specified type. QualType getBlockPointerType(QualType T) const; /// This gets the struct used to keep track of the descriptor for pointer to /// blocks. QualType getBlockDescriptorType() const; /// This gets the struct used to keep track of the extended descriptor for /// pointer to blocks. QualType getBlockDescriptorExtendedType() const; void setcudaConfigureCallDecl(FunctionDecl *FD) { cudaConfigureCallDecl = FD; } FunctionDecl *getcudaConfigureCallDecl() { return cudaConfigureCallDecl; } /// This builds the struct used for __block variables. QualType BuildByRefType(StringRef DeclName, QualType Ty) const; /// Returns true iff we need copy/dispose helpers for the given type. bool BlockRequiresCopying(QualType Ty) const; /// getLValueReferenceType - Return the uniqued reference to the type for an /// lvalue reference to the specified type. QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true) const; /// getRValueReferenceType - Return the uniqued reference to the type for an /// rvalue reference to the specified type. QualType getRValueReferenceType(QualType T) const; /// getMemberPointerType - Return the uniqued reference to the type for a /// member pointer to the specified type in the specified class. The class /// is a Type because it could be a dependent name. QualType getMemberPointerType(QualType T, const Type *Cls) const; /// getVariableArrayType - Returns a non-unique reference to the type for a /// variable array of the specified element type. QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const; /// getDependentSizedArrayType - Returns a non-unique reference to /// the type for a dependently-sized array of the specified element /// type. FIXME: We will need these to be uniqued, or at least /// comparable, at some point. QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const; /// getIncompleteArrayType - Returns a unique reference to the type for a /// incomplete array of the specified element type. QualType getIncompleteArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const; /// getConstantArrayType - Return the unique reference to the type for a /// constant array of the specified element type. QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const; /// getVariableArrayDecayedType - Returns a vla type where known sizes /// are replaced with [*]. QualType getVariableArrayDecayedType(QualType Ty) const; /// getVectorType - Return the unique reference to a vector type of /// the specified element type and size. VectorType must be a built-in type. QualType getVectorType(QualType VectorType, unsigned NumElts, VectorType::VectorKind VecKind) const; /// getExtVectorType - Return the unique reference to an extended vector type /// of the specified element type and size. VectorType must be a built-in /// type. QualType getExtVectorType(QualType VectorType, unsigned NumElts) const; /// getDependentSizedExtVectorType - Returns a non-unique reference to /// the type for a dependently-sized vector of the specified element /// type. FIXME: We will need these to be uniqued, or at least /// comparable, at some point. QualType getDependentSizedExtVectorType(QualType VectorType, Expr *SizeExpr, SourceLocation AttrLoc) const; /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const; QualType getFunctionNoProtoType(QualType ResultTy) const { return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo()); } /// getFunctionType - Return a normal function type with a typed /// argument list. QualType getFunctionType(QualType ResultTy, const QualType *Args, unsigned NumArgs, const FunctionProtoType::ExtProtoInfo &EPI) const; /// getTypeDeclType - Return the unique reference to the type for /// the specified type declaration. QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl = 0) const { assert(Decl && "Passed null for Decl param"); if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); if (PrevDecl) { assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl"); Decl->TypeForDecl = PrevDecl->TypeForDecl; return QualType(PrevDecl->TypeForDecl, 0); } return getTypeDeclTypeSlow(Decl); } /// getTypedefType - Return the unique reference to the type for the /// specified typedef-name decl. QualType getTypedefType(const TypedefNameDecl *Decl, QualType Canon = QualType()) const; QualType getRecordType(const RecordDecl *Decl) const; QualType getEnumType(const EnumDecl *Decl) const; QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const; QualType getAttributedType(AttributedType::Kind attrKind, QualType modifiedType, QualType equivalentType); QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced, QualType Replacement) const; QualType getSubstTemplateTypeParmPackType( const TemplateTypeParmType *Replaced, const TemplateArgument &ArgPack); QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, bool ParameterPack, TemplateTypeParmDecl *ParmDecl = 0) const; QualType getTemplateSpecializationType(TemplateName T, const TemplateArgument *Args, unsigned NumArgs, QualType Canon = QualType()) const; QualType getCanonicalTemplateSpecializationType(TemplateName T, const TemplateArgument *Args, unsigned NumArgs) const; QualType getTemplateSpecializationType(TemplateName T, const TemplateArgumentListInfo &Args, QualType Canon = QualType()) const; TypeSourceInfo * getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc, const TemplateArgumentListInfo &Args, QualType Canon = QualType()) const; QualType getParenType(QualType NamedType) const; QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType) const; QualType getDependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, 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, unsigned NumArgs, const TemplateArgument *Args) const; QualType getPackExpansionType(QualType Pattern, llvm::Optional NumExpansions); QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const; QualType getObjCObjectType(QualType Base, ObjCProtocolDecl * const *Protocols, unsigned NumProtocols) const; /// getObjCObjectPointerType - Return a ObjCObjectPointerType type /// for the given ObjCObjectType. QualType getObjCObjectPointerType(QualType OIT) const; /// getTypeOfType - GCC extension. QualType getTypeOfExprType(Expr *e) const; QualType getTypeOfType(QualType t) const; /// getDecltypeType - C++0x decltype. QualType getDecltypeType(Expr *e) const; /// getUnaryTransformType - unary type transforms QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType, UnaryTransformType::UTTKind UKind) const; /// getAutoType - C++0x deduced auto type. QualType getAutoType(QualType DeducedType) const; /// getAutoDeductType - C++0x deduction pattern for 'auto' type. QualType getAutoDeductType() const; /// getAutoRRefDeductType - C++0x deduction pattern for 'auto &&' type. QualType getAutoRRefDeductType() const; /// getTagDeclType - Return the unique reference to the type for the /// specified TagDecl (struct/union/class/enum) decl. QualType getTagDeclType(const TagDecl *Decl) const; /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined /// in . The sizeof operator requires this (C99 6.5.3.4p4). CanQualType getSizeType() const; /// getWCharType - In C++, this returns the unique wchar_t type. In C99, this /// returns a type compatible with the type defined in as defined /// by the target. QualType getWCharType() const { return WCharTy; } /// getSignedWCharType - Return the type of "signed wchar_t". /// Used when in C++, as a GCC extension. QualType getSignedWCharType() const; /// getUnsignedWCharType - Return the type of "unsigned wchar_t". /// Used when in C++, as a GCC extension. QualType getUnsignedWCharType() const; /// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?) /// defined in . Pointer - pointer requires this (C99 6.5.6p9). QualType getPointerDiffType() const; // getCFConstantStringType - Return the C structure type used to represent // constant CFStrings. QualType getCFConstantStringType() const; /// Get the structure type used to representation CFStrings, or NULL /// if it hasn't yet been built. QualType getRawCFConstantStringType() const { if (CFConstantStringTypeDecl) return getTagDeclType(CFConstantStringTypeDecl); return QualType(); } void setCFConstantStringType(QualType T); // This setter/getter represents the ObjC type for an NSConstantString. void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl); QualType getObjCConstantStringInterface() const { return ObjCConstantStringType; } /// \brief Retrieve the type that 'id' has been defined to, which may be /// different from the built-in 'id' if 'id' has been typedef'd. QualType getObjCIdRedefinitionType() const { if (ObjCIdRedefinitionType.isNull()) return getObjCIdType(); return ObjCIdRedefinitionType; } /// \brief Set the user-written type that redefines 'id'. void setObjCIdRedefinitionType(QualType RedefType) { ObjCIdRedefinitionType = RedefType; } /// \brief Retrieve the type that 'Class' has been defined to, which may be /// different from the built-in 'Class' if 'Class' has been typedef'd. QualType getObjCClassRedefinitionType() const { if (ObjCClassRedefinitionType.isNull()) return getObjCClassType(); return ObjCClassRedefinitionType; } /// \brief Set the user-written type that redefines 'SEL'. void setObjCClassRedefinitionType(QualType RedefType) { ObjCClassRedefinitionType = RedefType; } /// \brief Retrieve the type that 'SEL' has been defined to, which may be /// different from the built-in 'SEL' if 'SEL' has been typedef'd. QualType getObjCSelRedefinitionType() const { if (ObjCSelRedefinitionType.isNull()) return getObjCSelType(); return ObjCSelRedefinitionType; } /// \brief Set the user-written type that redefines 'SEL'. void setObjCSelRedefinitionType(QualType RedefType) { ObjCSelRedefinitionType = RedefType; } /// \brief Retrieve the Objective-C "instancetype" type, if already known; /// otherwise, returns a NULL type; QualType getObjCInstanceType() { return getTypeDeclType(getObjCInstanceTypeDecl()); } /// \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; } /// \brief Retrieve the C FILE type. QualType getFILEType() const { if (FILEDecl) return getTypeDeclType(FILEDecl); return QualType(); } /// \brief Set the type for the C jmp_buf type. void setjmp_bufDecl(TypeDecl *jmp_bufDecl) { this->jmp_bufDecl = jmp_bufDecl; } /// \brief Retrieve the C jmp_buf type. QualType getjmp_bufType() const { if (jmp_bufDecl) return getTypeDeclType(jmp_bufDecl); return QualType(); } /// \brief Set the type for the C sigjmp_buf type. void setsigjmp_bufDecl(TypeDecl *sigjmp_bufDecl) { this->sigjmp_bufDecl = sigjmp_bufDecl; } /// \brief Retrieve the C sigjmp_buf type. QualType getsigjmp_bufType() const { if (sigjmp_bufDecl) return getTypeDeclType(sigjmp_bufDecl); return QualType(); } /// \brief The result type of logical operations, '<', '>', '!=', etc. QualType getLogicalOperationType() const { return getLangOptions().CPlusPlus ? BoolTy : IntTy; } /// getObjCEncodingForType - Emit the ObjC type encoding for the /// given type into \arg S. If \arg NameFields is specified then /// record field names are also encoded. void getObjCEncodingForType(QualType t, std::string &S, const FieldDecl *Field=0) const; void getLegacyIntegralTypeEncoding(QualType &t) const; // Put the string version of type qualifiers into S. void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, std::string &S) const; /// getObjCEncodingForFunctionDecl - Returns the encoded type for this /// function. This is in the same format as Objective-C method encodings. /// /// \returns true if an error occurred (e.g., because one of the parameter /// types is incomplete), false otherwise. bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S); /// getObjCEncodingForMethodDecl - Return the encoded type for this method /// declaration. /// /// \returns true if an error occurred (e.g., because one of the parameter /// types is incomplete), false otherwise. bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S) const; /// getObjCEncodingForBlock - 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 /// only be NULL when getting encodings for protocol properties. void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container, std::string &S) const; bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, ObjCProtocolDecl *rProto) const; /// getObjCEncodingTypeSize returns size of type for objective-c encoding /// purpose in characters. CharUnits getObjCEncodingTypeSize(QualType t) const; /// \brief Retrieve the typedef corresponding to the predefined 'id' type /// in Objective-C. TypedefDecl *getObjCIdDecl() const; /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by /// Sema. id is always a (typedef for a) pointer type, a pointer to a struct. 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()); } void setObjCProtoType(QualType QT); QualType getObjCProtoType() const { return ObjCProtoType; } /// \brief Retrieve the typedef declaration corresponding to the predefined /// Objective-C 'Class' type. TypedefDecl *getObjCClassDecl() const; /// This setter/getter repreents the ObjC 'Class' type. It is setup lazily, by /// Sema. 'Class' is always a (typedef for a) pointer type, a pointer to a /// struct. QualType getObjCClassType() const { return getTypeDeclType(getObjCClassDecl()); } void setBuiltinVaListType(QualType T); QualType getBuiltinVaListType() const { return BuiltinVaListType; } /// getCVRQualifiedType - Returns a type with additional const, /// volatile, or restrict qualifiers. QualType getCVRQualifiedType(QualType T, unsigned CVR) const { return getQualifiedType(T, Qualifiers::fromCVRMask(CVR)); } /// getQualifiedType - Returns a type with additional qualifiers. QualType getQualifiedType(QualType T, Qualifiers Qs) const { if (!Qs.hasNonFastQualifiers()) return T.withFastQualifiers(Qs.getFastQualifiers()); QualifierCollector Qc(Qs); const Type *Ptr = Qc.strip(T); return getExtQualType(Ptr, Qc); } /// getQualifiedType - Returns a type with additional qualifiers. QualType getQualifiedType(const Type *T, Qualifiers Qs) const { if (!Qs.hasNonFastQualifiers()) return QualType(T, Qs.getFastQualifiers()); return getExtQualType(T, Qs); } /// getLifetimeQualifiedType - Returns a type with the given /// lifetime qualifier. QualType getLifetimeQualifiedType(QualType type, Qualifiers::ObjCLifetime lifetime) { assert(type.getObjCLifetime() == Qualifiers::OCL_None); assert(lifetime != Qualifiers::OCL_None); Qualifiers qs; qs.addObjCLifetime(lifetime); return getQualifiedType(type, qs); } DeclarationNameInfo getNameForTemplate(TemplateName Name, SourceLocation NameLoc) const; TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin, UnresolvedSetIterator End) const; TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateDecl *Template) const; TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, const IdentifierInfo *Name) const; TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, OverloadedOperatorKind Operator) const; TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param, TemplateName replacement) 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 }; /// GetBuiltinType - Return the type for the specified builtin. If /// IntegerConstantArgs is non-null, it is filled in with a bitmask of /// arguments to the builtin that are required to be integer constant /// expressions. QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs = 0) const; private: CanQualType getFromTargetType(unsigned Type) const; //===--------------------------------------------------------------------===// // Type Predicates. //===--------------------------------------------------------------------===// public: /// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's /// garbage collection attribute. /// Qualifiers::GC getObjCGCAttrKind(QualType Ty) const; /// areCompatibleVectorTypes - Return true if the given vector types /// are of the same unqualified type or if they are equivalent to the same /// GCC vector type, ignoring whether they are target-specific (AltiVec or /// Neon) types. bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec); /// isObjCNSObjectType - Return true if this is an NSObject object with /// its NSObject attribute set. static bool isObjCNSObjectType(QualType Ty) { return Ty->isObjCNSObjectType(); } //===--------------------------------------------------------------------===// // Type Sizing and Analysis //===--------------------------------------------------------------------===// /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified /// scalar floating point type. const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const; /// getTypeInfo - Get the size and alignment of the specified complete type in /// bits. std::pair getTypeInfo(const Type *T) const; std::pair getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); } /// getTypeSize - Return the size of the specified type, in bits. This method /// does not work on incomplete types. uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).first; } uint64_t getTypeSize(const Type *T) const { return getTypeInfo(T).first; } /// getCharWidth - Return the size of the character type, in bits uint64_t getCharWidth() const { return getTypeSize(CharTy); } /// toCharUnitsFromBits - Convert a size in bits to a size in characters. CharUnits toCharUnitsFromBits(int64_t BitSize) const; /// toBits - Convert a size in characters to a size in bits. int64_t toBits(CharUnits CharSize) const; /// getTypeSizeInChars - Return the size of the specified type, in characters. /// This method does not work on incomplete types. CharUnits getTypeSizeInChars(QualType T) const; CharUnits getTypeSizeInChars(const Type *T) const; /// getTypeAlign - Return the ABI-specified alignment of a type, in bits. /// This method does not work on incomplete types. unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).second; } unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).second; } /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in /// characters. This method does not work on incomplete types. CharUnits getTypeAlignInChars(QualType T) const; CharUnits getTypeAlignInChars(const Type *T) const; std::pair getTypeInfoInChars(const Type *T) const; std::pair getTypeInfoInChars(QualType T) const; /// getPreferredTypeAlign - Return the "preferred" alignment of the specified /// type for the current target in bits. This can be different than the ABI /// alignment in cases where it is beneficial for performance to overalign /// a data type. unsigned getPreferredTypeAlign(const Type *T) const; /// getDeclAlign - Return a conservative estimate of the alignment of /// the specified decl. Note that bitfields do not have a valid alignment, so /// this method will assert on them. /// If @p RefAsPointee, references are treated like their underlying type /// (for alignof), else they're treated like pointers (for CodeGen). CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false) const; /// getASTRecordLayout - Get or compute information about the layout of the /// specified record (struct/union/class), which indicates its size and field /// position information. const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const; /// getASTObjCInterfaceLayout - Get or compute information about the /// layout of the specified Objective-C interface. const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const; void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS) const; /// getASTObjCImplementationLayout - Get or compute information about /// the layout of the specified Objective-C implementation. This may /// differ from the interface if synthesized ivars are present. const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const; /// getKeyFunction - Get the key function for the given record decl, or NULL /// if there isn't one. The key function is, according to the Itanium C++ ABI /// section 5.2.3: /// /// ...the first non-pure virtual function that is not inline at the point /// of class definition. const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD); bool isNearlyEmpty(const CXXRecordDecl *RD) const; MangleContext *createMangleContext(); void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass, SmallVectorImpl &Ivars) const; unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const; void CollectInheritedProtocols(const Decl *CDecl, llvm::SmallPtrSet &Protocols); //===--------------------------------------------------------------------===// // Type Operators //===--------------------------------------------------------------------===// /// getCanonicalType - Return the canonical (structural) type corresponding to /// the specified potentially non-canonical type. The non-canonical version /// of a type may have many "decorated" versions of types. Decorators can /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed /// to be free of any of these, allowing two canonical types to be compared /// for exact equality with a simple pointer comparison. CanQualType getCanonicalType(QualType T) const { return CanQualType::CreateUnsafe(T.getCanonicalType()); } const Type *getCanonicalType(const Type *T) const { return T->getCanonicalTypeInternal().getTypePtr(); } /// getCanonicalParamType - Return the canonical parameter type /// corresponding to the specific potentially non-canonical one. /// Qualifiers are stripped off, functions are turned into function /// pointers, and arrays decay one level into pointers. CanQualType getCanonicalParamType(QualType T) const; /// \brief Determine whether the given types are equivalent. bool hasSameType(QualType T1, QualType T2) { return getCanonicalType(T1) == getCanonicalType(T2); } /// \brief Returns this type as a completely-unqualified array type, /// capturing the qualifiers in Quals. This will remove the minimal amount of /// sugaring from the types, similar to the behavior of /// QualType::getUnqualifiedType(). /// /// \param T is the qualified type, which may be an ArrayType /// /// \param Quals will receive the full set of qualifiers that were /// applied to the array. /// /// \returns if this is an array type, the completely unqualified array type /// that corresponds to it. Otherwise, returns T.getUnqualifiedType(). QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals); /// \brief Determine whether the given types are equivalent after /// cvr-qualifiers have been removed. bool hasSameUnqualifiedType(QualType T1, QualType T2) { return getCanonicalType(T1).getTypePtr() == getCanonicalType(T2).getTypePtr(); } bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2); /// \brief Retrieves the "canonical" nested name specifier for a /// given nested name specifier. /// /// The canonical nested name specifier is a nested name specifier /// that uniquely identifies a type or namespace within the type /// system. For example, given: /// /// \code /// namespace N { /// struct S { /// template struct X { typename T* type; }; /// }; /// } /// /// template struct Y { /// typename N::S::X::type member; /// }; /// \endcode /// /// Here, the nested-name-specifier for N::S::X:: will be /// S::X, since 'S' and 'X' are uniquely defined /// by declarations in the type system and the canonical type for /// the template type parameter 'T' is template-param-0-0. NestedNameSpecifier * getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const; /// \brief Retrieves the default calling convention to use for /// C++ instance methods. CallingConv getDefaultMethodCallConv(); /// \brief Retrieves the canonical representation of the given /// calling convention. CallingConv getCanonicalCallConv(CallingConv CC) const { if (!LangOpts.MRTD && CC == CC_C) return CC_Default; return CC; } /// \brief Determines whether two calling conventions name the same /// calling convention. bool isSameCallConv(CallingConv lcc, CallingConv rcc) { return (getCanonicalCallConv(lcc) == getCanonicalCallConv(rcc)); } /// \brief Retrieves the "canonical" template name that refers to a /// given template. /// /// The canonical template name is the simplest expression that can /// be used to refer to a given template. For most templates, this /// expression is just the template declaration itself. For example, /// the template std::vector can be referred to via a variety of /// names---std::vector, ::std::vector, vector (if vector is in /// scope), etc.---but all of these names map down to the same /// TemplateDecl, which is used to form the canonical template name. /// /// Dependent template names are more interesting. Here, the /// template name could be something like T::template apply or /// std::allocator::template rebind, where the nested name /// specifier itself is dependent. In this case, the canonical /// template name uses the shortest form of the dependent /// nested-name-specifier, which itself contains all canonical /// types, values, and templates. TemplateName getCanonicalTemplateName(TemplateName Name) const; /// \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; /// Type Query functions. If the type is an instance of the specified class, /// return the Type pointer for the underlying maximally pretty type. This /// is a member of ASTContext because this may need to do some amount of /// canonicalization, e.g. to move type qualifiers into the element type. const ArrayType *getAsArrayType(QualType T) const; const ConstantArrayType *getAsConstantArrayType(QualType T) const { return dyn_cast_or_null(getAsArrayType(T)); } const VariableArrayType *getAsVariableArrayType(QualType T) const { return dyn_cast_or_null(getAsArrayType(T)); } const IncompleteArrayType *getAsIncompleteArrayType(QualType T) const { return dyn_cast_or_null(getAsArrayType(T)); } const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T) const { return dyn_cast_or_null(getAsArrayType(T)); } /// getBaseElementType - Returns the innermost element type of an array type. /// For example, will return "int" for int[m][n] QualType getBaseElementType(const ArrayType *VAT) const; /// getBaseElementType - Returns the innermost element type of a type /// (which needn't actually be an array type). QualType getBaseElementType(QualType QT) const; /// getConstantArrayElementCount - Returns number of constant array elements. uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const; /// \brief Perform adjustment on the parameter type of a function. /// /// This routine adjusts the given parameter type @p T to the actual /// 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); /// \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); /// getArrayDecayedType - Return the properly qualified result of decaying the /// specified array type to a pointer. This operation is non-trivial when /// handling typedefs etc. The canonical type of "T" must be an array type, /// this returns a pointer to a properly qualified element of the array. /// /// See C99 6.7.5.3p7 and C99 6.3.2.1p3. QualType getArrayDecayedType(QualType T) const; /// getPromotedIntegerType - Returns the type that Promotable will /// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable /// integer type. QualType getPromotedIntegerType(QualType PromotableType) const; /// \brief Recurses in pointer/array types until it finds an objc retainable /// type and returns its ownership. Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const; /// \brief Whether this is a promotable bitfield reference according /// to C99 6.3.1.1p2, bullet 2 (and GCC extensions). /// /// \returns the type this bit-field will promote to, or NULL if no /// promotion occurs. QualType isPromotableBitField(Expr *E) const; /// getIntegerTypeOrder - Returns the highest ranked integer type: /// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If /// LHS < RHS, return -1. int getIntegerTypeOrder(QualType LHS, QualType RHS) const; /// getFloatingTypeOrder - Compare the rank of the two specified floating /// point types, ignoring the domain of the type (i.e. 'double' == /// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If /// LHS < RHS, return -1. int getFloatingTypeOrder(QualType LHS, QualType RHS) const; /// getFloatingTypeOfSizeWithinDomain - Returns a real floating /// point or a complex type (based on typeDomain/typeSize). /// 'typeDomain' is a real floating point or complex type. /// 'typeSize' is a real floating point or complex type. QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize, QualType typeDomain) const; unsigned getTargetAddressSpace(QualType T) const { return getTargetAddressSpace(T.getQualifiers()); } unsigned getTargetAddressSpace(Qualifiers Q) const { return getTargetAddressSpace(Q.getAddressSpace()); } unsigned getTargetAddressSpace(unsigned AS) const { if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count) return AS; else return (*AddrSpaceMap)[AS - LangAS::Offset]; } private: // Helper for integer ordering unsigned getIntegerRank(const Type *T) const; public: //===--------------------------------------------------------------------===// // Type Compatibility Predicates //===--------------------------------------------------------------------===// /// Compatibility predicates used to check assignment expressions. bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified = false); // C99 6.2.7p1 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 QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS); 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 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, bool Unqualified = false, bool BlockReturnType = false); QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified = false); QualType mergeFunctionArgumentTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified = false); QualType mergeTransparentUnionType(QualType, QualType, bool OfBlockPointer=false, bool Unqualified = false); QualType mergeObjCGCQualifiers(QualType, QualType); bool FunctionTypesMatchOnNSConsumedAttrs( const FunctionProtoType *FromFunctionType, const FunctionProtoType *ToFunctionType); void ResetObjCLayout(const ObjCContainerDecl *CD) { ObjCLayouts[CD] = 0; } //===--------------------------------------------------------------------===// // Integer Predicates //===--------------------------------------------------------------------===// // The width of an integer, as defined in C99 6.2.6.2. This is the number // of bits in an integer type excluding any padding bits. unsigned getIntWidth(QualType T) const; // Per C99 6.2.5p6, for every signed integer type, there is a corresponding // unsigned integer type. This method takes a signed type, and returns the // corresponding unsigned integer type. QualType getCorrespondingUnsignedType(QualType T); //===--------------------------------------------------------------------===// // Type Iterators. //===--------------------------------------------------------------------===// typedef std::vector::iterator type_iterator; typedef std::vector::const_iterator const_type_iterator; type_iterator types_begin() { return Types.begin(); } type_iterator types_end() { return Types.end(); } const_type_iterator types_begin() const { return Types.begin(); } const_type_iterator types_end() const { return Types.end(); } //===--------------------------------------------------------------------===// // Integer Values //===--------------------------------------------------------------------===// /// MakeIntValue - Make an APSInt of the appropriate width and /// signedness for the given \arg Value and integer \arg Type. llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const { llvm::APSInt Res(getIntWidth(Type), !Type->isSignedIntegerOrEnumerationType()); Res = Value; return Res; } /// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists. ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D); /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists. ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D); /// \brief returns true if there is at lease one @implementation in TU. bool AnyObjCImplementation() { return !ObjCImpls.empty(); } /// \brief Set the implementation of ObjCInterfaceDecl. void setObjCImplementation(ObjCInterfaceDecl *IFaceD, ObjCImplementationDecl *ImplD); /// \brief Set the implementation of ObjCCategoryDecl. void setObjCImplementation(ObjCCategoryDecl *CatD, ObjCCategoryImplDecl *ImplD); /// \brief Get the duplicate declaration of a ObjCMethod in the same /// interface, or null if non exists. const ObjCMethodDecl *getObjCMethodRedeclaration( const ObjCMethodDecl *MD) const { llvm::DenseMap::const_iterator I = ObjCMethodRedecls.find(MD); if (I == ObjCMethodRedecls.end()) return 0; return I->second; } void setObjCMethodRedeclaration(const ObjCMethodDecl *MD, const ObjCMethodDecl *Redecl) { ObjCMethodRedecls[MD] = Redecl; } /// \brief Set the copy inialization expression of a block var decl. void setBlockVarCopyInits(VarDecl*VD, Expr* Init); /// \brief Get the copy initialization expression of VarDecl,or NULL if /// none exists. Expr *getBlockVarCopyInits(const VarDecl*VD); /// \brief Allocate an uninitialized TypeSourceInfo. /// /// The caller should initialize the memory held by TypeSourceInfo using /// the TypeLoc wrappers. /// /// \param T the type that will be the basis for type source info. This type /// should refer to how the declarator was written in source code, not to /// what type semantic analysis resolved the declarator to. /// /// \param Size the size of the type info to create, or 0 if the size /// should be calculated based on the type. TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0) const; /// \brief Allocate a TypeSourceInfo where all locations have been /// initialized to a given location, which defaults to the empty /// location. TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation()) const; TypeSourceInfo *getNullTypeSourceInfo() { return &NullTypeSourceInfo; } /// \brief Add a deallocation callback that will be invoked when the /// ASTContext is destroyed. /// /// \brief Callback A callback function that will be invoked on destruction. /// /// \brief Data Pointer data that will be provided to the callback function /// when it is called. void AddDeallocation(void (*Callback)(void*), void *Data); GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD); GVALinkage GetGVALinkageForVariable(const VarDecl *VD); /// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH /// lazily, only when used; this is only relevant for function or file scoped /// var definitions. /// /// \returns true if the function/var must be CodeGen'ed/deserialized even if /// it is not used. bool DeclMustBeEmitted(const Decl *D); /// \brief Used by ParmVarDecl to store on the side the /// index of the parameter when it exceeds the size of the normal bitfield. void setParameterIndex(const ParmVarDecl *D, unsigned index); /// \brief Used by ParmVarDecl to retrieve on the side the /// index of the parameter when it exceeds the size of the normal bitfield. unsigned getParameterIndex(const ParmVarDecl *D) const; //===--------------------------------------------------------------------===// // Statistics //===--------------------------------------------------------------------===// /// \brief The number of implicitly-declared default constructors. static unsigned NumImplicitDefaultConstructors; /// \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 /// which declarations were built. static unsigned NumImplicitCopyConstructorsDeclared; /// \brief The number of implicitly-declared move constructors. static unsigned NumImplicitMoveConstructors; /// \brief The number of implicitly-declared move constructors for /// which declarations were built. static unsigned NumImplicitMoveConstructorsDeclared; /// \brief The number of implicitly-declared copy assignment operators. static unsigned NumImplicitCopyAssignmentOperators; /// \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 /// 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 /// declarations were built. static unsigned NumImplicitDestructorsDeclared; private: ASTContext(const ASTContext&); // DO NOT IMPLEMENT void operator=(const ASTContext&); // DO NOT IMPLEMENT public: /// \brief Initialize built-in types. /// /// This routine may only be invoked once for a given ASTContext object. /// It is normally invoked by the ASTContext constructor. However, the /// constructor can be asked to delay initialization, which places the burden /// of calling this function on the user of that object. /// /// \param Target The target void InitBuiltinTypes(const TargetInfo &Target); private: void InitBuiltinType(CanQualType &R, BuiltinType::Kind K); // Return the ObjC 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) const; // Adds the encoding of the structure's members. void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S, const FieldDecl *Field, bool includeVBases = true) const; const ASTRecordLayout & getObjCLayout(const ObjCInterfaceDecl *D, const ObjCImplementationDecl *Impl) const; private: /// \brief A set of deallocations that should be performed when the /// ASTContext is destroyed. SmallVector, 16> Deallocations; // 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; /// \brief A counter used to uniquely identify "blocks". mutable unsigned int UniqueBlockByRefTypeID; friend class DeclContext; friend class DeclarationNameTable; void ReleaseDeclContextMaps(); }; /// @brief Utility function for constructing a nullary selector. 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); return Ctx.Selectors.getSelector(1, &II); } } // end namespace clang // operator new and delete aren't allowed inside namespaces. // The throw specifications are mandated by the standard. /// @brief Placement new for using the ASTContext's allocator. /// /// This placement form of operator new uses the ASTContext's allocator for /// obtaining memory. It is a non-throwing new, which means that it returns /// null on error. (If that is what the allocator does. The current does, so if /// this ever changes, this operator will have to be changed, too.) /// Usage looks like this (assuming there's an ASTContext 'Context' in scope): /// @code /// // Default alignment (8) /// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments); /// // Specific alignment /// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments); /// @endcode /// Please note that you cannot use delete on the pointer; it must be /// deallocated using an explicit destructor call followed by /// @c Context.Deallocate(Ptr). /// /// @param Bytes The number of bytes to allocate. Calculated by the compiler. /// @param C The ASTContext that provides the allocator. /// @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, size_t Alignment) throw () { return C.Allocate(Bytes, Alignment); } /// @brief Placement delete companion to the new above. /// /// This operator is just a companion to the new above. There is no way of /// invoking it directly; see the new operator for more details. This operator /// is called implicitly by the compiler if a placement new expression using /// the ASTContext throws in the object constructor. inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) throw () { C.Deallocate(Ptr); } /// This placement form of operator new[] uses the ASTContext's allocator for /// obtaining memory. It is a non-throwing new[], which means that it returns /// null on error. /// Usage looks like this (assuming there's an ASTContext 'Context' in scope): /// @code /// // Default alignment (8) /// char *data = new (Context) char[10]; /// // Specific alignment /// char *data = new (Context, 4) char[10]; /// @endcode /// Please note that you cannot use delete on the pointer; it must be /// deallocated using an explicit destructor call followed by /// @c Context.Deallocate(Ptr). /// /// @param Bytes The number of bytes to allocate. Calculated by the compiler. /// @param C The ASTContext that provides the allocator. /// @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, size_t Alignment = 8) throw () { return C.Allocate(Bytes, Alignment); } /// @brief Placement delete[] companion to the new[] above. /// /// This operator is just a companion to the new[] above. There is no way of /// invoking it directly; see the new[] operator for more details. This operator /// is called implicitly by the compiler if a placement new[] expression using /// the ASTContext throws in the object constructor. inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) throw () { C.Deallocate(Ptr); } #endif