diff options
-rw-r--r-- | include/clang/AST/Type.h | 149 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/MemRegion.h | 4 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 111 | ||||
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 6 |
6 files changed, 206 insertions, 79 deletions
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index cef52175d1..89776b91fe 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -483,7 +483,9 @@ public: return CVR; } - bool isConstant(ASTContext& Ctx) const; + bool isConstant(ASTContext& Ctx) const { + return QualType::isConstant(*this, Ctx); + } // Don't promise in the API that anything besides 'const' can be // easily added. @@ -548,7 +550,9 @@ public: /// concrete. /// /// Qualifiers are left in place. - QualType getDesugaredType(bool ForDisplay = false) const; + QualType getDesugaredType() const { + return QualType::getDesugaredType(*this); + } /// operator==/!= - Indicate whether the specified types and qualifiers are /// identical. @@ -594,6 +598,13 @@ public: /// getNoReturnAttr - Returns true if the type has the noreturn attribute, /// false otherwise. bool getNoReturnAttr() const; + +private: + // These methods are implemented in a separate translation unit; + // "static"-ize them to avoid creating temporary QualTypes in the + // caller. + static bool isConstant(QualType T, ASTContext& Ctx); + static QualType getDesugaredType(QualType T); }; } // end clang. @@ -842,13 +853,10 @@ public: /// pointer, this returns the respective pointee. QualType getPointeeType() const; - /// getDesugaredType - Return the specified type with any "sugar" removed from - /// the type. This takes off typedefs, typeof's etc. If the outer level of - /// the type is already concrete, it returns it unmodified. This is similar - /// to getting the canonical type, but it doesn't remove *all* typedefs. For - /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is - /// concrete. - QualType getDesugaredType(bool ForDisplay = false) const; + /// getUnqualifiedDesugaredType() - Return the specified type with + /// any "sugar" removed from the type, removing any typedefs, + /// typeofs, etc., as well as any qualifiers. + const Type *getUnqualifiedDesugaredType() const; /// More type predicates useful for type checking/promotion bool isPromotableIntegerType() const; // C99 6.3.1.1p2 @@ -946,6 +954,9 @@ public: Kind getKind() const { return TypeKind; } const char *getName(const LangOptions &LO) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; @@ -968,6 +979,9 @@ public: bool isSigned() const { return Signed; } const char *getName() const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; @@ -991,6 +1005,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType()); } @@ -1018,6 +1035,9 @@ public: QualType getPointeeType() const { return PointeeType; } + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType()); } @@ -1048,6 +1068,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType()); } @@ -1099,6 +1122,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { return T->getTypeClass() == LValueReference; } @@ -1116,6 +1142,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { return T->getTypeClass() == RValueReference; } @@ -1145,6 +1174,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType(), getClass()); } @@ -1237,6 +1269,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType(), getSize(), getSizeModifier(), getIndexTypeCVRQualifiers()); @@ -1286,6 +1321,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { return T->getTypeClass() == ConstantArrayWithExpr; } @@ -1314,6 +1352,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { return T->getTypeClass() == ConstantArrayWithoutExpr; } @@ -1337,6 +1378,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { return T->getTypeClass() == IncompleteArray; } @@ -1400,6 +1444,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { return T->getTypeClass() == VariableArray; } @@ -1453,6 +1500,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { return T->getTypeClass() == DependentSizedArray; } @@ -1502,6 +1552,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { return T->getTypeClass() == DependentSizedExtVector; } @@ -1544,6 +1597,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType(), getNumElements(), getTypeClass()); } @@ -1619,6 +1675,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { return T->getTypeClass() == ExtVector; } @@ -1661,7 +1720,6 @@ public: QualType getResultType() const { return ResultType; } bool getNoReturnAttr() const { return NoReturn; } - static bool classof(const Type *T) { return T->getTypeClass() == FunctionNoProto || T->getTypeClass() == FunctionProto; @@ -1683,6 +1741,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getResultType(), getNoReturnAttr()); } @@ -1793,6 +1854,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const Type *T) { return T->getTypeClass() == FunctionProto; } @@ -1828,6 +1892,9 @@ public: /// looking through the typedefs for B will give you "const volatile A". QualType LookThroughTypedefs() const; + bool isSugared() const { return true; } + QualType desugar() const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; @@ -1845,6 +1912,12 @@ protected: public: Expr *getUnderlyingExpr() const { return TOExpr; } + /// \brief Remove a single level of sugar. + QualType desugar() const; + + /// \brief Returns whether this type directly provides sugar. + bool isSugared() const { return true; } + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; @@ -1862,6 +1935,9 @@ public: DependentTypeOfExprType(ASTContext &Context, Expr *E) : TypeOfExprType(E), Context(Context) { } + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Context, getUnderlyingExpr()); } @@ -1881,6 +1957,12 @@ class TypeOfType : public Type { public: QualType getUnderlyingType() const { return TOType; } + /// \brief Remove a single level of sugar. + QualType desugar() const { return getUnderlyingType(); } + + /// \brief Returns whether this type directly provides sugar. + bool isSugared() const { return true; } + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; @@ -1904,6 +1986,12 @@ public: Expr *getUnderlyingExpr() const { return E; } QualType getUnderlyingType() const { return UnderlyingType; } + /// \brief Remove a single level of sugar. + QualType desugar() const { return getUnderlyingType(); } + + /// \brief Returns whether this type directly provides sugar. + bool isSugared() const { return !isDependentType(); } + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; @@ -1919,6 +2007,9 @@ class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode { public: DependentDecltypeType(ASTContext &Context, Expr *E); + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Context, getUnderlyingExpr()); } @@ -1983,6 +2074,9 @@ public: // the same address space, and return that. unsigned getAddressSpace() const { return 0; } + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const TagType *T); static bool classof(const Type *T) { return isa<TagType>(T) && classof(cast<TagType>(T)); @@ -2002,6 +2096,9 @@ public: return reinterpret_cast<EnumDecl*>(TagType::getDecl()); } + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + static bool classof(const TagType *T); static bool classof(const Type *T) { return isa<TagType>(T) && classof(cast<TagType>(T)); @@ -2043,6 +2140,12 @@ public: TagKind getTagKind() const { return Tag; } QualType getUnderlyingType() const { return UnderlyingType; } + /// \brief Remove a single level of sugar. + QualType desugar() const { return getUnderlyingType(); } + + /// \brief Returns whether this type directly provides sugar. + bool isSugared() const { return true; } + static const char *getNameForTagKind(TagKind Kind) { switch (Kind) { default: assert(0 && "Unknown TagKind!"); @@ -2094,6 +2197,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Depth, Index, ParameterPack, Name); } @@ -2185,6 +2291,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return !isDependentType(); } + QualType desugar() const { return getCanonicalTypeInternal(); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Template, getArgs(), NumArgs, Context); } @@ -2227,6 +2336,12 @@ public: /// \brief Retrieve the type named by the qualified-id. QualType getNamedType() const { return NamedType; } + /// \brief Remove a single level of sugar. + QualType desugar() const { return getNamedType(); } + + /// \brief Returns whether this type directly provides sugar. + bool isSugared() const { return true; } + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; @@ -2307,6 +2422,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, NNS, Name); } @@ -2357,6 +2475,9 @@ public: virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, const ObjCInterfaceDecl *Decl, @@ -2432,6 +2553,9 @@ public: /// interface type, or 0 if there are none. unsigned getNumProtocols() const { return Protocols.size(); } + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, QualType T, ObjCProtocolDecl **protocols, unsigned NumProtocols); @@ -2472,6 +2596,9 @@ public: /// \brief Return the number of qualifying protocols. unsigned getNumProtocols() const { return Protocols.size(); } + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, QualType T, ObjCProtocolDecl **protocols, unsigned NumProtocols); @@ -2803,7 +2930,7 @@ template <typename T> const T *Type::getAs() const { // If this is a typedef for the type, strip the typedef off without // losing all typedef information. - return cast<T>(getDesugaredType()); + return cast<T>(getUnqualifiedDesugaredType()); } } // end namespace clang diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h index ae0580afa4..0e487691a8 100644 --- a/include/clang/Analysis/PathSensitive/MemRegion.h +++ b/include/clang/Analysis/PathSensitive/MemRegion.h @@ -218,11 +218,11 @@ public: QualType getDesugaredValueType(ASTContext& C) const { QualType T = getValueType(C); - return T.getTypePtr() ? T->getDesugaredType() : T; + return T.getTypePtr() ? T.getDesugaredType() : T; } QualType getDesugaredLocationType(ASTContext& C) const { - return getLocationType(C)->getDesugaredType(); + return getLocationType(C).getDesugaredType(); } bool isBoundable() const { diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 70b9fa5946..0293862bae 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -22,12 +22,12 @@ #include "llvm/Support/raw_ostream.h" using namespace clang; -bool QualType::isConstant(ASTContext &Ctx) const { - if (isConstQualified()) +bool QualType::isConstant(QualType T, ASTContext &Ctx) { + if (T.isConstQualified()) return true; - if (getTypePtr()->isArrayType()) - return Ctx.getAsArrayType(*this)->getElementType().isConstant(Ctx); + if (const ArrayType *AT = Ctx.getAsArrayType(T)) + return AT->getElementType().isConstant(Ctx); return false; } @@ -106,7 +106,8 @@ const Type *Type::getArrayElementTypeNoTypeQual() const { // If this is a typedef for an array type, strip the typedef off without // losing all typedef information. - return cast<ArrayType>(getDesugaredType())->getElementType().getTypePtr(); + return cast<ArrayType>(getUnqualifiedDesugaredType()) + ->getElementType().getTypePtr(); } /// getDesugaredType - Return the specified type with any "sugar" removed from @@ -115,62 +116,46 @@ const Type *Type::getArrayElementTypeNoTypeQual() const { /// to getting the canonical type, but it doesn't remove *all* typedefs. For /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is /// concrete. -/// -/// \param ForDisplay When true, the desugaring is provided for -/// display purposes only. In this case, we apply more heuristics to -/// decide whether it is worth providing a desugared form of the type -/// or not. -QualType QualType::getDesugaredType(bool ForDisplay) const { +QualType QualType::getDesugaredType(QualType T) { QualifierCollector Qs; - return Qs.apply(Qs.strip(*this)->getDesugaredType(ForDisplay)); -} -/// getDesugaredType - Return the specified type with any "sugar" removed from -/// type type. This takes off typedefs, typeof's etc. If the outer level of -/// the type is already concrete, it returns it unmodified. This is similar -/// to getting the canonical type, but it doesn't remove *all* typedefs. For -/// example, it return "T*" as "T*", (not as "int*"), because the pointer is -/// concrete. -/// -/// \param ForDisplay When true, the desugaring is provided for -/// display purposes only. In this case, we apply more heuristics to -/// decide whether it is worth providing a desugared form of the type -/// or not. -QualType Type::getDesugaredType(bool ForDisplay) const { - if (const TypedefType *TDT = dyn_cast<TypedefType>(this)) - return TDT->LookThroughTypedefs().getDesugaredType(); - if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(this)) - return ET->getUnderlyingType().getDesugaredType(); - if (const TypeOfExprType *TOE = dyn_cast<TypeOfExprType>(this)) - return TOE->getUnderlyingExpr()->getType().getDesugaredType(); - if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this)) - return TOT->getUnderlyingType().getDesugaredType(); - if (const DecltypeType *DTT = dyn_cast<DecltypeType>(this)) { - if (!DTT->getUnderlyingType()->isDependentType()) - return DTT->getUnderlyingType().getDesugaredType(); - } - if (const TemplateSpecializationType *Spec - = dyn_cast<TemplateSpecializationType>(this)) { - if (ForDisplay) - return QualType(this, 0); - - QualType Canon = Spec->getCanonicalTypeInternal(); - if (Canon->getAs<TemplateSpecializationType>()) - return QualType(this, 0); - return Canon->getDesugaredType(); - } - if (const QualifiedNameType *QualName = dyn_cast<QualifiedNameType>(this)) { - if (ForDisplay) { - // If desugaring the type that the qualified name is referring to - // produces something interesting, that's our desugared type. - QualType NamedType = QualName->getNamedType().getDesugaredType(); - if (NamedType != QualName->getNamedType()) - return NamedType; - } else - return QualName->getNamedType().getDesugaredType(); + QualType Cur = T; + while (true) { + const Type *CurTy = Qs.strip(Cur); + switch (CurTy->getTypeClass()) { +#define ABSTRACT_TYPE(Class, Parent) +#define TYPE(Class, Parent) \ + case Type::Class: { \ + const Class##Type *Ty = cast<Class##Type>(CurTy); \ + if (!Ty->isSugared()) \ + return Qs.apply(Cur); \ + Cur = Ty->desugar(); \ + break; \ + } +#include "clang/AST/TypeNodes.def" + } } +} - return QualType(this, 0); +/// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic +/// sugar off the given type. This should produce an object of the +/// same dynamic type as the canonical type. +const Type *Type::getUnqualifiedDesugaredType() const { + const Type *Cur = this; + + while (true) { + switch (Cur->getTypeClass()) { +#define ABSTRACT_TYPE(Class, Parent) +#define TYPE(Class, Parent) \ + case Class: { \ + const Class##Type *Ty = cast<Class##Type>(Cur); \ + if (!Ty->isSugared()) return Cur; \ + Cur = Ty->desugar().getTypePtr(); \ + break; \ + } +#include "clang/AST/TypeNodes.def" + } + } } /// isVoidType - Helper method to determine if this is the 'void' type. @@ -303,7 +288,7 @@ const RecordType *Type::getAsStructureType() const { // If this is a typedef for a structure type, strip the typedef off without // losing all typedef information. - return cast<RecordType>(getDesugaredType()); + return cast<RecordType>(getUnqualifiedDesugaredType()); } return 0; } @@ -322,7 +307,7 @@ const RecordType *Type::getAsUnionType() const { // If this is a typedef for a union type, strip the typedef off without // losing all typedef information. - return cast<RecordType>(getDesugaredType()); + return cast<RecordType>(getUnqualifiedDesugaredType()); } return 0; @@ -790,10 +775,18 @@ QualType TypedefType::LookThroughTypedefs() const { return Qs.apply(CurType); } +QualType TypedefType::desugar() const { + return getDecl()->getUnderlyingType(); +} + TypeOfExprType::TypeOfExprType(Expr *E, QualType can) : Type(TypeOfExpr, can, E->isTypeDependent()), TOExpr(E) { } +QualType TypeOfExprType::desugar() const { + return getUnderlyingExpr()->getType(); +} + void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context, Expr *E) { E->Profile(ID, Context, true); diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index f63e9d874e..7a433dd148 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -770,7 +770,7 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) { return UnknownVal(); // Strip off typedefs from the ArrayRegion's ValueType. - QualType T = ArrayR->getValueType(getContext())->getDesugaredType(); + QualType T = ArrayR->getValueType(getContext()).getDesugaredType(); ArrayType *AT = cast<ArrayType>(T); T = AT->getElementType(); diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 81f7283e23..3aae2563d1 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -44,16 +44,23 @@ static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val, // If this is a sugared type (like a typedef, typeof, etc), then unwrap one // level of the sugar so that the type is more obvious to the user. - QualType DesugaredTy = Ty.getDesugaredType(true); + QualType DesugaredTy = Ty.getDesugaredType(); if (Ty != DesugaredTy && // If the desugared type is a vector type, we don't want to expand it, // it will turn into an attribute mess. People want their "vec4". !isa<VectorType>(DesugaredTy) && - // Don't aka just because we saw an elaborated type. + // Don't aka just because we saw an elaborated type... (!isa<ElaboratedType>(Ty) || - cast<ElaboratedType>(Ty)->getUnderlyingType() != DesugaredTy) && + cast<ElaboratedType>(Ty)->desugar() != DesugaredTy) && + + // ...or a qualified name type... + (!isa<QualifiedNameType>(Ty) || + cast<QualifiedNameType>(Ty)->desugar() != DesugaredTy) && + + // ...or a non-dependent template specialization. + (!isa<TemplateSpecializationType>(Ty) || Ty->isDependentType()) && // Don't desugar magic Objective-C types. Ty.getUnqualifiedType() != Context.getObjCIdType() && diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 7aa0261ff6..223662afce 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1267,7 +1267,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, assert(BaseClass && "ActOnMemInitializers - neither field or base"); Diag(Member->getSourceLocation(), diag::error_multiple_base_initialization) - << BaseClass->getDesugaredType(true); + << QualType(BaseClass, 0); } Diag(PrevMember->getSourceLocation(), diag::note_previous_initializer) << 0; @@ -1336,7 +1336,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, Type *BaseClass = PrevMember->getBaseClass(); Diag(PrevMember->getSourceLocation(), diag::warn_base_initialized) - << BaseClass->getDesugaredType(true); + << QualType(BaseClass, 0); } else { FieldDecl *Field = PrevMember->getMember(); Diag(PrevMember->getSourceLocation(), @@ -1352,7 +1352,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, Type *BaseClass = Member->getBaseClass(); Diag(Member->getSourceLocation(), diag::note_fieldorbase_initialized_here) << 1 - << BaseClass->getDesugaredType(true); + << QualType(BaseClass, 0); } for (curIndex = 0; curIndex < Last; curIndex++) if (MemberInCtorList == AllBaseOrMembers[curIndex]) |