diff options
Diffstat (limited to 'include/clang/AST/Type.h')
-rw-r--r-- | include/clang/AST/Type.h | 137 |
1 files changed, 102 insertions, 35 deletions
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 7b615c19dcc4..6564b66548a4 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -29,6 +29,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/Twine.h" #include "clang/Basic/LLVM.h" namespace clang { @@ -377,8 +378,6 @@ public: return hasConst(); } - bool isSupersetOf(Qualifiers Other) const; - /// \brief Determine whether this set of qualifiers is a strict superset of /// another set of qualifiers, not considering qualifier compatibility. bool isStrictSupersetOf(Qualifiers Other) const; @@ -412,12 +411,11 @@ public: } std::string getAsString() const; - std::string getAsString(const PrintingPolicy &Policy) const { - std::string Buffer; - getAsStringInternal(Buffer, Policy); - return Buffer; - } - void getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const; + std::string getAsString(const PrintingPolicy &Policy) const; + + bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const; + void print(raw_ostream &OS, const PrintingPolicy &Policy, + bool appendSpaceIfNonEmpty = false) const; void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Mask); @@ -522,8 +520,6 @@ public: void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); } /// Retrieves a pointer to the underlying (unqualified) type. - /// This should really return a const Type, but it's not worth - /// changing all the users right now. /// /// This function requires that the type not be NULL. If the type might be /// NULL, use the (slightly less efficient) \c getTypePtrOrNull(). @@ -634,6 +630,11 @@ public: /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). bool isPODType(ASTContext &Context) const; + /// isCXX98PODType() - Return true if this is a POD type according to the + /// rules of the C++98 standard, regardless of the current compilation's + /// language. + bool isCXX98PODType(ASTContext &Context) const; + /// isCXX11PODType() - Return true if this is a POD type according to the /// more relaxed rules of the C++11 standard, regardless of the current /// compilation's language. @@ -824,11 +825,20 @@ public: } static std::string getAsString(const Type *ty, Qualifiers qs); - std::string getAsString(const PrintingPolicy &Policy) const { - std::string S; - getAsStringInternal(S, Policy); - return S; + std::string getAsString(const PrintingPolicy &Policy) const; + + void print(raw_ostream &OS, const PrintingPolicy &Policy, + const Twine &PlaceHolder = Twine()) const { + print(split(), OS, Policy, PlaceHolder); + } + static void print(SplitQualType split, raw_ostream &OS, + const PrintingPolicy &policy, const Twine &PlaceHolder) { + return print(split.Ty, split.Quals, OS, policy, PlaceHolder); } + static void print(const Type *ty, Qualifiers qs, + raw_ostream &OS, const PrintingPolicy &policy, + const Twine &PlaceHolder); + void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const { return getAsStringInternal(split(), Str, Policy); @@ -841,6 +851,27 @@ public: std::string &out, const PrintingPolicy &policy); + class StreamedQualTypeHelper { + const QualType &T; + const PrintingPolicy &Policy; + const Twine &PlaceHolder; + public: + StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, + const Twine &PlaceHolder) + : T(T), Policy(Policy), PlaceHolder(PlaceHolder) { } + + friend raw_ostream &operator<<(raw_ostream &OS, + const StreamedQualTypeHelper &SQT) { + SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder); + return OS; + } + }; + + StreamedQualTypeHelper stream(const PrintingPolicy &Policy, + const Twine &PlaceHolder = Twine()) const { + return StreamedQualTypeHelper(*this, Policy, PlaceHolder); + } + void dump(const char *s) const; void dump() const; @@ -1107,8 +1138,6 @@ private: unsigned TC : 8; /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]). - /// Note that this should stay at the end of the ivars for Type so that - /// subclasses can pack their bitfields into the same word. unsigned Dependent : 1; /// \brief Whether this type somehow involves a template parameter, even @@ -1614,7 +1643,7 @@ public: AutoType *getContainedAutoType() const; /// Member-template getAs<specific type>'. Look through sugar for - /// an instance of <specific type>. This scheme will eventually + /// an instance of \<specific type>. This scheme will eventually /// replace the specific getAsXXXX methods above. /// /// There are some specializations of this member template listed @@ -1626,7 +1655,7 @@ public: const ArrayType *getAsArrayTypeUnsafe() const; /// Member-template castAs<specific type>. Look through sugar for - /// the underlying instance of <specific type>. + /// the underlying instance of \<specific type>. /// /// This method has the same relationship to getAs<T> as cast<T> has /// to dyn_cast<T>; which is to say, the underlying type *must* @@ -1715,9 +1744,9 @@ public: friend class ASTWriter; }; -template <> inline const TypedefType *Type::getAs() const { - return dyn_cast<TypedefType>(this); -} +/// \brief This will check for a TypedefType by removing any existing sugar +/// until it reaches a TypedefType or a non-sugared type. +template <> const TypedefType *Type::getAs() const; // We can do canonical leaf types faster, because we don't have to // worry about preserving child type decoration. @@ -1752,7 +1781,13 @@ public: } Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); } - const char *getName(const PrintingPolicy &Policy) const; + StringRef getName(const PrintingPolicy &Policy) const; + const char *getNameAsCString(const PrintingPolicy &Policy) const { + // The StringRef is null-terminated. + StringRef str = getName(Policy); + assert(!str.empty() && str.data()[str.size()] == '\0'); + return str.data(); + } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2641,6 +2676,9 @@ public: bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } CallingConv getCallConv() const { return getExtInfo().getCC(); } ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } + bool isConst() const { return getTypeQuals() & Qualifiers::Const; } + bool isVolatile() const { return getTypeQuals() & Qualifiers::Volatile; } + bool isRestrict() const { return getTypeQuals() & Qualifiers::Restrict; } /// \brief Determine the type of an expression that calls a function of /// this type. @@ -2808,6 +2846,8 @@ public: } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { EPI.ExceptionSpecDecl = getExceptionSpecDecl(); EPI.ExceptionSpecTemplate = getExceptionSpecTemplate(); + } else if (EPI.ExceptionSpecType == EST_Unevaluated) { + EPI.ExceptionSpecDecl = getExceptionSpecDecl(); } if (hasAnyConsumedArgs()) EPI.ConsumedArguments = getConsumedArgsBuffer(); @@ -2851,11 +2891,13 @@ public: // NoexceptExpr sits where the arguments end. return *reinterpret_cast<Expr *const *>(arg_type_end()); } - /// \brief If this function type has an uninstantiated exception - /// specification, this is the function whose exception specification - /// is represented by this type. + /// \brief If this function type has an exception specification which hasn't + /// been determined yet (either because it has not been evaluated or because + /// it has not been instantiated), this is the function whose exception + /// specification is represented by this type. FunctionDecl *getExceptionSpecDecl() const { - if (getExceptionSpecType() != EST_Uninstantiated) + if (getExceptionSpecType() != EST_Uninstantiated && + getExceptionSpecType() != EST_Unevaluated) return 0; return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[0]; } @@ -2870,7 +2912,7 @@ public: } bool isNothrow(ASTContext &Ctx) const { ExceptionSpecificationType EST = getExceptionSpecType(); - assert(EST != EST_Delayed && EST != EST_Uninstantiated); + assert(EST != EST_Unevaluated && EST != EST_Uninstantiated); if (EST == EST_DynamicNone || EST == EST_BasicNoexcept) return true; if (EST != EST_ComputedNoexcept) @@ -2928,8 +2970,11 @@ public: bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } + // FIXME: Remove the string version. void printExceptionSpecification(std::string &S, PrintingPolicy Policy) const; + void printExceptionSpecification(raw_ostream &OS, + PrintingPolicy Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == FunctionProto; @@ -3582,6 +3627,7 @@ public: /// \brief Print a template argument list, including the '<' and '>' /// enclosing the template arguments. + // FIXME: remove the string ones. static std::string PrintTemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs, const PrintingPolicy &Policy, @@ -3594,6 +3640,23 @@ public: static std::string PrintTemplateArgumentList(const TemplateArgumentListInfo &, const PrintingPolicy &Policy); + /// \brief Print a template argument list, including the '<' and '>' + /// enclosing the template arguments. + static void PrintTemplateArgumentList(raw_ostream &OS, + const TemplateArgument *Args, + unsigned NumArgs, + const PrintingPolicy &Policy, + bool SkipBrackets = false); + + static void PrintTemplateArgumentList(raw_ostream &OS, + const TemplateArgumentLoc *Args, + unsigned NumArgs, + const PrintingPolicy &Policy); + + static void PrintTemplateArgumentList(raw_ostream &OS, + const TemplateArgumentListInfo &, + const PrintingPolicy &Policy); + /// True if this template specialization type matches a current /// instantiation in the context in which it is found. bool isCurrentInstantiation() const { @@ -3641,7 +3704,7 @@ public: unsigned getNumArgs() const { return NumArgs; } /// \brief Retrieve a specific template argument as a type. - /// \precondition @c isArgType(Arg) + /// \pre @c isArgType(Arg) const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h bool isSugared() const { @@ -4045,7 +4108,7 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode { PackExpansionType(QualType Pattern, QualType Canon, llvm::Optional<unsigned> NumExpansions) - : Type(PackExpansion, Canon, /*Dependent=*/true, + : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), /*InstantiationDependent=*/true, /*VariableModified=*/Pattern->isVariablyModifiedType(), /*ContainsUnexpandedParameterPack=*/false), @@ -4097,8 +4160,10 @@ public: /// list of protocols. /// /// Given the following declarations: -/// @class C; -/// @protocol P; +/// \code +/// \@class C; +/// \@protocol P; +/// \endcode /// /// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType /// with base C and no protocols. @@ -4312,11 +4377,13 @@ public: /// This method is equivalent to getPointeeType() except that /// it discards any typedefs (or other sugar) between this /// type and the "outermost" object type. So for: - /// @class A; @protocol P; @protocol Q; + /// \code + /// \@class A; \@protocol P; \@protocol Q; /// typedef A<P> AP; /// typedef A A1; /// typedef A1<P> A1P; /// typedef A1P<Q> A1PQ; + /// \endcode /// For 'A*', getObjectType() will return 'A'. /// For 'A<P>*', getObjectType() will return 'A<P>'. /// For 'AP*', getObjectType() will return 'A<P>'. @@ -4333,7 +4400,7 @@ public: } /// getInterfaceType - If this pointer points to an Objective C - /// @interface type, gets the type for that interface. Any protocol + /// \@interface type, gets the type for that interface. Any protocol /// qualifiers on the interface are ignored. /// /// \return null if the base type for this pointer is 'id' or 'Class' @@ -4341,7 +4408,7 @@ public: return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>(); } - /// getInterfaceDecl - If this pointer points to an Objective @interface + /// getInterfaceDecl - If this pointer points to an Objective \@interface /// type, gets the declaration for that interface. /// /// \return null if the base type for this pointer is 'id' or 'Class' @@ -4970,7 +5037,7 @@ struct ArrayType_cannot_be_used_with_getAs { }; template<typename T> struct ArrayType_cannot_be_used_with_getAs<T, true>; -/// Member-template getAs<specific type>'. +// Member-template getAs<specific type>'. template <typename T> const T *Type::getAs() const { ArrayType_cannot_be_used_with_getAs<T> at; (void)at; |