diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 141 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 39 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 7 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 23 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 23 | ||||
-rw-r--r-- | lib/Index/ResolveLocation.cpp | 45 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 18 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 205 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 50 |
10 files changed, 244 insertions, 310 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 292f2ac95d..7f5fa35842 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -555,10 +555,6 @@ ASTContext::getTypeInfo(const Type *T) { assert(false && "Should not see dependent types"); break; - case Type::ObjCProtocolList: - assert(false && "Should not see protocol list types"); - break; - case Type::FunctionNoProto: case Type::FunctionProto: // GCC extension: alignof(function) = 32 bits @@ -1235,22 +1231,25 @@ QualType ASTContext::getBlockPointerType(QualType T) { /// getLValueReferenceType - Return the uniqued reference to the type for an /// lvalue reference to the specified type. -QualType ASTContext::getLValueReferenceType(QualType T) { +QualType ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) { // Unique pointers, to guarantee there is only one pointer of a particular // structure. llvm::FoldingSetNodeID ID; - ReferenceType::Profile(ID, T); + ReferenceType::Profile(ID, T, SpelledAsLValue); void *InsertPos = 0; if (LValueReferenceType *RT = LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(RT, 0); + const ReferenceType *InnerRef = T->getAs<ReferenceType>(); + // If the referencee type isn't canonical, this won't be a canonical type // either, so fill in the canonical type field. QualType Canonical; - if (!T.isCanonical()) { - Canonical = getLValueReferenceType(getCanonicalType(T)); + if (!SpelledAsLValue || InnerRef || !T.isCanonical()) { + QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T); + Canonical = getLValueReferenceType(getCanonicalType(PointeeType)); // Get the new insert position for the node we care about. LValueReferenceType *NewIP = @@ -1259,9 +1258,11 @@ QualType ASTContext::getLValueReferenceType(QualType T) { } LValueReferenceType *New - = new (*this, TypeAlignment) LValueReferenceType(T, Canonical); + = new (*this, TypeAlignment) LValueReferenceType(T, Canonical, + SpelledAsLValue); Types.push_back(New); LValueReferenceTypes.InsertNode(New, InsertPos); + return QualType(New, 0); } @@ -1271,18 +1272,21 @@ QualType ASTContext::getRValueReferenceType(QualType T) { // Unique pointers, to guarantee there is only one pointer of a particular // structure. llvm::FoldingSetNodeID ID; - ReferenceType::Profile(ID, T); + ReferenceType::Profile(ID, T, false); void *InsertPos = 0; if (RValueReferenceType *RT = RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(RT, 0); + const ReferenceType *InnerRef = T->getAs<ReferenceType>(); + // If the referencee type isn't canonical, this won't be a canonical type // either, so fill in the canonical type field. QualType Canonical; - if (!T.isCanonical()) { - Canonical = getRValueReferenceType(getCanonicalType(T)); + if (InnerRef || !T.isCanonical()) { + QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T); + Canonical = getRValueReferenceType(getCanonicalType(PointeeType)); // Get the new insert position for the node we care about. RValueReferenceType *NewIP = @@ -1603,12 +1607,6 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, unsigned TypeQuals, bool hasExceptionSpec, bool hasAnyExceptionSpec, unsigned NumExs, const QualType *ExArray, bool NoReturn) { - if (LangOpts.CPlusPlus) { - for (unsigned i = 0; i != NumArgs; ++i) - assert(!ArgArray[i].hasQualifiers() && - "C++ arguments can't have toplevel qualifiers!"); - } - // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; @@ -1622,11 +1620,9 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, return QualType(FTP, 0); // Determine whether the type being created is already canonical or not. - bool isCanonical = ResultTy.isCanonical(); - if (hasExceptionSpec) - isCanonical = false; + bool isCanonical = !hasExceptionSpec && ResultTy.isCanonical(); for (unsigned i = 0; i != NumArgs && isCanonical; ++i) - if (!ArgArray[i].isCanonical()) + if (!ArgArray[i].isCanonicalAsParam()) isCanonical = false; // If this type isn't canonical, get the canonical version of it. @@ -1636,7 +1632,7 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, llvm::SmallVector<QualType, 16> CanonicalArgs; CanonicalArgs.reserve(NumArgs); for (unsigned i = 0; i != NumArgs; ++i) - CanonicalArgs.push_back(getCanonicalType(ArgArray[i])); + CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i])); Canonical = getFunctionType(getCanonicalType(ResultTy), CanonicalArgs.data(), NumArgs, @@ -1920,7 +1916,17 @@ static bool CmpProtocolNames(const ObjCProtocolDecl *LHS, return LHS->getDeclName() < RHS->getDeclName(); } -static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols, +static bool areSortedAndUniqued(ObjCProtocolDecl **Protocols, + unsigned NumProtocols) { + if (NumProtocols == 0) return true; + + for (unsigned i = 1; i != NumProtocols; ++i) + if (!CmpProtocolNames(Protocols[i-1], Protocols[i])) + return false; + return true; +} + +static void SortAndUniqueProtocols(ObjCProtocolDecl **Protocols, unsigned &NumProtocols) { ObjCProtocolDecl **ProtocolsEnd = Protocols+NumProtocols; @@ -1937,10 +1943,6 @@ static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols, QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT, ObjCProtocolDecl **Protocols, unsigned NumProtocols) { - // Sort the protocol list alphabetically to canonicalize it. - if (NumProtocols) - SortAndUniqueProtocols(Protocols, NumProtocols); - llvm::FoldingSetNodeID ID; ObjCObjectPointerType::Profile(ID, InterfaceT, Protocols, NumProtocols); @@ -1949,9 +1951,31 @@ QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT, ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(QT, 0); + // Sort the protocol list alphabetically to canonicalize it. + QualType Canonical; + if (!InterfaceT.isCanonical() || + !areSortedAndUniqued(Protocols, NumProtocols)) { + if (!areSortedAndUniqued(Protocols, NumProtocols)) { + llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(NumProtocols); + unsigned UniqueCount = NumProtocols; + + std::copy(Protocols, Protocols + NumProtocols, Sorted.begin()); + SortAndUniqueProtocols(&Sorted[0], UniqueCount); + + Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT), + &Sorted[0], UniqueCount); + } else { + Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT), + Protocols, NumProtocols); + } + + // Regenerate InsertPos. + ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos); + } + // No Match; ObjCObjectPointerType *QType = new (*this, TypeAlignment) - ObjCObjectPointerType(InterfaceT, Protocols, NumProtocols); + ObjCObjectPointerType(Canonical, InterfaceT, Protocols, NumProtocols); Types.push_back(QType); ObjCObjectPointerTypes.InsertNode(QType, InsertPos); @@ -1962,10 +1986,6 @@ QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT, /// specified ObjC interface decl. The list of protocols is optional. QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCProtocolDecl **Protocols, unsigned NumProtocols) { - if (NumProtocols) - // Sort the protocol list alphabetically to canonicalize it. - SortAndUniqueProtocols(Protocols, NumProtocols); - llvm::FoldingSetNodeID ID; ObjCInterfaceType::Profile(ID, Decl, Protocols, NumProtocols); @@ -1974,31 +1994,26 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(QT, 0); - // No Match; - ObjCInterfaceType *QType = new (*this, TypeAlignment) - ObjCInterfaceType(const_cast<ObjCInterfaceDecl*>(Decl), - Protocols, NumProtocols); - Types.push_back(QType); - ObjCInterfaceTypes.InsertNode(QType, InsertPos); - return QualType(QType, 0); -} + // Sort the protocol list alphabetically to canonicalize it. + QualType Canonical; + if (NumProtocols && !areSortedAndUniqued(Protocols, NumProtocols)) { + llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(NumProtocols); + std::copy(Protocols, Protocols + NumProtocols, Sorted.begin()); -QualType ASTContext::getObjCProtocolListType(QualType T, - ObjCProtocolDecl **Protocols, - unsigned NumProtocols) { - llvm::FoldingSetNodeID ID; - ObjCProtocolListType::Profile(ID, T, Protocols, NumProtocols); + unsigned UniqueCount = NumProtocols; + SortAndUniqueProtocols(&Sorted[0], UniqueCount); - void *InsertPos = 0; - if (ObjCProtocolListType *QT = - ObjCProtocolListTypes.FindNodeOrInsertPos(ID, InsertPos)) - return QualType(QT, 0); + Canonical = getObjCInterfaceType(Decl, &Sorted[0], UniqueCount); + + ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos); + } + + ObjCInterfaceType *QType = new (*this, TypeAlignment) + ObjCInterfaceType(Canonical, const_cast<ObjCInterfaceDecl*>(Decl), + Protocols, NumProtocols); - // No Match; - ObjCProtocolListType *QType = new (*this, TypeAlignment) - ObjCProtocolListType(T, Protocols, NumProtocols); Types.push_back(QType); - ObjCProtocolListTypes.InsertNode(QType, InsertPos); + ObjCInterfaceTypes.InsertNode(QType, InsertPos); return QualType(QType, 0); } @@ -2155,6 +2170,24 @@ QualType ASTContext::getPointerDiffType() const { // Type Operators //===----------------------------------------------------------------------===// +CanQualType ASTContext::getCanonicalParamType(QualType T) { + // Push qualifiers into arrays, and then discard any remaining + // qualifiers. + T = getCanonicalType(T); + const Type *Ty = T.getTypePtr(); + + QualType Result; + if (isa<ArrayType>(Ty)) { + Result = getArrayDecayedType(QualType(Ty,0)); + } else if (isa<FunctionType>(Ty)) { + Result = getPointerType(QualType(Ty, 0)); + } else { + Result = QualType(Ty, 0); + } + + return CanQualType::CreateUnsafe(Result); +} + /// 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 diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index daa2bc04f1..5fb0178834 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -724,18 +724,6 @@ void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType(), 0, 0); } -void ObjCProtocolListType::Profile(llvm::FoldingSetNodeID &ID, - QualType OIT, ObjCProtocolDecl **protocols, - unsigned NumProtocols) { - ID.AddPointer(OIT.getAsOpaquePtr()); - for (unsigned i = 0; i != NumProtocols; i++) - ID.AddPointer(protocols[i]); -} - -void ObjCProtocolListType::Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getBaseType(), &Protocols[0], getNumProtocols()); -} - /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to /// potentially looking through *all* consequtive typedefs. This returns the /// sum of the type qualifiers, so if you have: @@ -1059,10 +1047,10 @@ void LValueReferenceType::getAsStringInternal(std::string &S, const PrintingPoli // Handle things like 'int (&A)[4];' correctly. // FIXME: this should include vectors, but vectors use attributes I guess. - if (isa<ArrayType>(getPointeeType())) + if (isa<ArrayType>(getPointeeTypeAsWritten())) S = '(' + S + ')'; - getPointeeType().getAsStringInternal(S, Policy); + getPointeeTypeAsWritten().getAsStringInternal(S, Policy); } void RValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { @@ -1070,10 +1058,10 @@ void RValueReferenceType::getAsStringInternal(std::string &S, const PrintingPoli // Handle things like 'int (&&A)[4];' correctly. // FIXME: this should include vectors, but vectors use attributes I guess. - if (isa<ArrayType>(getPointeeType())) + if (isa<ArrayType>(getPointeeTypeAsWritten())) S = '(' + S + ')'; - getPointeeType().getAsStringInternal(S, Policy); + getPointeeTypeAsWritten().getAsStringInternal(S, Policy); } void MemberPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { @@ -1463,25 +1451,6 @@ void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString, InnerString = ObjCQIString + InnerString; } -void ObjCProtocolListType::getAsStringInternal(std::string &InnerString, - const PrintingPolicy &Policy) const { - if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. - InnerString = ' ' + InnerString; - - std::string ObjCQIString = getBaseType().getAsString(Policy); - ObjCQIString += '<'; - bool isFirst = true; - for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) { - if (isFirst) - isFirst = false; - else - ObjCQIString += ','; - ObjCQIString += (*I)->getNameAsString(); - } - ObjCQIString += '>'; - InnerString = ObjCQIString + InnerString; -} - void ElaboratedType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { std::string TypeStr; diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 155f87a41d..2e6034bbcd 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -248,7 +248,12 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { FD = PrimaryTemplate->getTemplatedDecl(); } - mangleBareFunctionType(FD->getType()->getAs<FunctionType>(), MangleReturnType); + // Do the canonicalization out here because parameter types can + // undergo additional canonicalization (e.g. array decay). + FunctionType *FT = cast<FunctionType>(Context.getASTContext() + .getCanonicalType(FD->getType())); + + mangleBareFunctionType(FT, MangleReturnType); } static bool isStdNamespace(const DeclContext *DC) { diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index c02959f2cc..7dc60f8e99 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -1964,16 +1964,6 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { return Context->getObjCObjectPointerType(OIT, Protos.data(), NumProtos); } - case pch::TYPE_OBJC_PROTOCOL_LIST: { - unsigned Idx = 0; - QualType OIT = GetType(Record[Idx++]); - unsigned NumProtos = Record[Idx++]; - llvm::SmallVector<ObjCProtocolDecl*, 4> Protos; - for (unsigned I = 0; I != NumProtos; ++I) - Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++]))); - return Context->getObjCProtocolListType(OIT, Protos.data(), NumProtos); - } - case pch::TYPE_SUBST_TEMPLATE_TYPE_PARM: { unsigned Idx = 0; QualType Parm = GetType(Record[Idx++]); @@ -2124,15 +2114,20 @@ void TypeLocReader::VisitTypenameTypeLoc(TypenameTypeLoc TL) { } void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) + TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++])); } void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} -void TypeLocReader::VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) { TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) - TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setHasBaseTypeAsWritten(Record[Idx++]); + TL.setHasProtocolsAsWritten(Record[Idx++]); + if (TL.hasProtocolsAsWritten()) + for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) + TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++])); } DeclaratorInfo *PCHReader::GetDeclaratorInfo(const RecordData &Record, diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index c98080a38b..fb48df3321 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -248,15 +248,6 @@ PCHTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { Code = pch::TYPE_OBJC_OBJECT_POINTER; } -void PCHTypeWriter::VisitObjCProtocolListType(const ObjCProtocolListType *T) { - Writer.AddTypeRef(T->getBaseType(), Record); - Record.push_back(T->getNumProtocols()); - for (ObjCProtocolListType::qual_iterator I = T->qual_begin(), - E = T->qual_end(); I != E; ++I) - Writer.AddDeclRef(*I, Record); - Code = pch::TYPE_OBJC_PROTOCOL_LIST; -} - namespace { class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { @@ -387,15 +378,20 @@ void TypeLocWriter::VisitTypenameTypeLoc(TypenameTypeLoc TL) { } void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); + Writer.AddSourceLocation(TL.getLAngleLoc(), Record); + Writer.AddSourceLocation(TL.getRAngleLoc(), Record); + for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) + Writer.AddSourceLocation(TL.getProtocolLoc(i), Record); } void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { Writer.AddSourceLocation(TL.getStarLoc(), Record); -} -void TypeLocWriter::VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) { Writer.AddSourceLocation(TL.getLAngleLoc(), Record); Writer.AddSourceLocation(TL.getRAngleLoc(), Record); - for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) - Writer.AddSourceLocation(TL.getProtocolLoc(i), Record); + Record.push_back(TL.hasBaseTypeAsWritten()); + Record.push_back(TL.hasProtocolsAsWritten()); + if (TL.hasProtocolsAsWritten()) + for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) + Writer.AddSourceLocation(TL.getProtocolLoc(i), Record); } //===----------------------------------------------------------------------===// @@ -569,7 +565,6 @@ void PCHWriter::WriteBlockInfoBlock() { RECORD(TYPE_ENUM); RECORD(TYPE_OBJC_INTERFACE); RECORD(TYPE_OBJC_OBJECT_POINTER); - RECORD(TYPE_OBJC_PROTOCOL_LIST); RECORD(DECL_ATTR); RECORD(DECL_TRANSLATION_UNIT); RECORD(DECL_TYPEDEF); diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp index d3ba8192b2..8edd634f8a 100644 --- a/lib/Index/ResolveLocation.cpp +++ b/lib/Index/ResolveLocation.cpp @@ -120,11 +120,12 @@ public: TypeLocResolver(ASTContext &ctx, SourceLocation loc, Decl *pd) : LocResolverBase(ctx, loc), ParentDecl(pd) { } + ASTLocation VisitBuiltinTypeLoc(BuiltinTypeLoc TL); ASTLocation VisitTypedefTypeLoc(TypedefTypeLoc TL); ASTLocation VisitFunctionTypeLoc(FunctionTypeLoc TL); ASTLocation VisitArrayTypeLoc(ArrayTypeLoc TL); ASTLocation VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL); - ASTLocation VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL); + ASTLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL); ASTLocation VisitTypeLoc(TypeLoc TL); }; @@ -349,6 +350,24 @@ ASTLocation DeclLocResolver::VisitDecl(Decl *D) { return ASTLocation(D); } +ASTLocation TypeLocResolver::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { + // Continue the 'id' magic by making the builtin type (which cannot + // actually be spelled) map to the typedef. + BuiltinType *T = TL.getTypePtr(); + if (T->getKind() == BuiltinType::ObjCId) { + TypedefDecl *D = Ctx.getObjCIdType()->getAs<TypedefType>()->getDecl(); + return ASTLocation(ParentDecl, D, TL.getNameLoc()); + } + + // Same thing with 'Class'. + if (T->getKind() == BuiltinType::ObjCClass) { + TypedefDecl *D = Ctx.getObjCClassType()->getAs<TypedefType>()->getDecl(); + return ASTLocation(ParentDecl, D, TL.getNameLoc()); + } + + return ASTLocation(ParentDecl, TL); +} + ASTLocation TypeLocResolver::VisitTypedefTypeLoc(TypedefTypeLoc TL) { assert(ContainsLocation(TL) && "Should visit only after verifying that loc is in range"); @@ -389,12 +408,6 @@ ASTLocation TypeLocResolver::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) "Should visit only after verifying that loc is in range"); if (ContainsLocation(TL.getNameLoc())) return ASTLocation(ParentDecl, TL.getIFaceDecl(), TL.getNameLoc()); - return ASTLocation(ParentDecl, TL); -} - -ASTLocation TypeLocResolver::VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) { - assert(ContainsLocation(TL) && - "Should visit only after verifying that loc is in range"); for (unsigned i = 0; i != TL.getNumProtocols(); ++i) { SourceLocation L = TL.getProtocolLoc(i); @@ -408,6 +421,24 @@ ASTLocation TypeLocResolver::VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLo return ASTLocation(ParentDecl, TL); } +ASTLocation TypeLocResolver::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { + assert(ContainsLocation(TL) && + "Should visit only after verifying that loc is in range"); + + if (TL.hasProtocolsAsWritten()) { + for (unsigned i = 0; i != TL.getNumProtocols(); ++i) { + SourceLocation L = TL.getProtocolLoc(i); + RangePos RP = CheckRange(L); + if (RP == AfterLoc) + break; + if (RP == ContainsLoc) + return ASTLocation(ParentDecl, TL.getProtocol(i), L); + } + } + + return ASTLocation(ParentDecl, TL); +} + ASTLocation TypeLocResolver::VisitTypeLoc(TypeLoc TL) { assert(ContainsLocation(TL) && "Should visit only after verifying that loc is in range"); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 074a6fcb62..6dd081bdc2 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -448,7 +448,7 @@ public: // QualType adjustParameterType(QualType T); QualType ConvertDeclSpecToType(const DeclSpec &DS, SourceLocation DeclLoc, - bool &IsInvalid, QualType &SourceTy); + bool &IsInvalid); void ProcessTypeAttributeList(QualType &Result, const AttributeList *AL); QualType BuildPointerType(QualType T, unsigned Quals, SourceLocation Loc, DeclarationName Entity); @@ -3755,22 +3755,6 @@ public: QualType FieldTy, const Expr *BitWidth, bool *ZeroWidth = 0); - /// adjustFunctionParamType - Converts the type of a function parameter to a - // type that can be passed as an argument type to - /// ASTContext::getFunctionType. - /// - /// C++ [dcl.fct]p3: "...Any cv-qualifier modifying a parameter type is - /// deleted. Such cv-qualifiers affect only the definition of the parameter - /// within the body of the function; they do not affect the function type. - QualType adjustFunctionParamType(QualType T) const { - if (!Context.getLangOptions().CPlusPlus) - return T; - return - T->isDependentType() ? T.getUnqualifiedType() - : T.getDesugaredType().getUnqualifiedType(); - - } - /// \name Code completion //@{ void setCodeCompleteConsumer(CodeCompleteConsumer *CCC); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index e083c07431..6d1f4ea4a8 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -4281,8 +4281,7 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S, // friend templates because ActOnTag never produces a ClassTemplateDecl // for a TUK_Friend. bool invalid = false; - QualType SourceTy; - QualType T = ConvertDeclSpecToType(DS, Loc, invalid, SourceTy); + QualType T = ConvertDeclSpecToType(DS, Loc, invalid); if (invalid) return DeclPtrTy(); // This is definitely an error in C++98. It's probably meant to diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 219ac3e582..49f7119c8b 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -52,16 +52,14 @@ QualType Sema::adjustParameterType(QualType T) { /// object. /// \param DS the declaration specifiers /// \param DeclLoc The location of the declarator identifier or invalid if none. -/// \param SourceTy QualType representing the type as written in source form. /// \returns The type described by the declaration specifiers. This function /// never returns null. QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, SourceLocation DeclLoc, - bool &isInvalid, QualType &SourceTy) { + bool &isInvalid) { // FIXME: Should move the logic from DeclSpec::Finish to here for validity // checking. QualType Result; - SourceTy = Result; switch (DS.getTypeSpecType()) { case DeclSpec::TST_void: @@ -106,9 +104,6 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, case DeclSpec::TST_unspecified: // "<proto1,proto2>" is an objc qualified ID with a missing id. if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) { - SourceTy = Context.getObjCProtocolListType(QualType(), - (ObjCProtocolDecl**)PQ, - DS.getNumProtocolQualifiers()); Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy, (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers()); @@ -226,9 +221,6 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, Result = GetTypeFromParser(DS.getTypeRep()); if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) { - SourceTy = Context.getObjCProtocolListType(Result, - (ObjCProtocolDecl**)PQ, - DS.getNumProtocolQualifiers()); if (const ObjCInterfaceType * Interface = Result->getAs<ObjCInterfaceType>()) { // It would be nice if protocol qualifiers were only stored with the @@ -385,8 +377,6 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, Result = Context.getQualifiedType(Result, Quals); } - if (SourceTy.isNull()) - SourceTy = Result; return Result; } @@ -450,36 +440,32 @@ QualType Sema::BuildPointerType(QualType T, unsigned Quals, /// /// \returns A suitable reference type, if there are no /// errors. Otherwise, returns a NULL type. -QualType Sema::BuildReferenceType(QualType T, bool LValueRef, unsigned CVR, - SourceLocation Loc, DeclarationName Entity) { +QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue, + unsigned CVR, SourceLocation Loc, + DeclarationName Entity) { Qualifiers Quals = Qualifiers::fromCVRMask(CVR); - if (LValueRef) { - if (const RValueReferenceType *R = T->getAs<RValueReferenceType>()) { - // C++0x [dcl.typedef]p9: If a typedef TD names a type that is a - // reference to a type T, and attempt to create the type "lvalue - // reference to cv TD" creates the type "lvalue reference to T". - // We use the qualifiers (restrict or none) of the original reference, - // not the new ones. This is consistent with GCC. - QualType LVRT = Context.getLValueReferenceType(R->getPointeeType()); - return Context.getQualifiedType(LVRT, T.getQualifiers()); - } - } - if (T->isReferenceType()) { - // C++ [dcl.ref]p4: There shall be no references to references. - // - // According to C++ DR 106, references to references are only - // diagnosed when they are written directly (e.g., "int & &"), - // but not when they happen via a typedef: - // - // typedef int& intref; - // typedef intref& intref2; - // - // Parser::ParseDeclaratorInternal diagnoses the case where - // references are written directly; here, we handle the - // collapsing of references-to-references as described in C++ - // DR 106 and amended by C++ DR 540. - return T; - } + + bool LValueRef = SpelledAsLValue || T->getAs<LValueReferenceType>(); + + // C++0x [dcl.typedef]p9: If a typedef TD names a type that is a + // reference to a type T, and attempt to create the type "lvalue + // reference to cv TD" creates the type "lvalue reference to T". + // We use the qualifiers (restrict or none) of the original reference, + // not the new ones. This is consistent with GCC. + + // C++ [dcl.ref]p4: There shall be no references to references. + // + // According to C++ DR 106, references to references are only + // diagnosed when they are written directly (e.g., "int & &"), + // but not when they happen via a typedef: + // + // typedef int& intref; + // typedef intref& intref2; + // + // Parser::ParseDeclaratorInternal diagnoses the case where + // references are written directly; here, we handle the + // collapsing of references-to-references as described in C++ + // DR 106 and amended by C++ DR 540. // C++ [dcl.ref]p1: // A declarator that specifies the type "reference to cv void" @@ -511,7 +497,8 @@ QualType Sema::BuildReferenceType(QualType T, bool LValueRef, unsigned CVR, // Handle restrict on references. if (LValueRef) - return Context.getQualifiedType(Context.getLValueReferenceType(T), Quals); + return Context.getQualifiedType( + Context.getLValueReferenceType(T, SpelledAsLValue), Quals); return Context.getQualifiedType(Context.getRValueReferenceType(T), Quals); } @@ -717,7 +704,7 @@ QualType Sema::BuildFunctionType(QualType T, Invalid = true; } - ParamTypes[Idx] = adjustFunctionParamType(ParamType); + ParamTypes[Idx] = ParamType; } if (Invalid) @@ -856,9 +843,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, // Determine the type of the declarator. Not all forms of declarator // have a type. QualType T; - // The QualType referring to the type as written in source code. We can't use - // T because it can change due to semantic analysis. - QualType SourceTy; switch (D.getKind()) { case Declarator::DK_Abstract: @@ -872,7 +856,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, T = Context.DependentTy; } else { bool isInvalid = false; - T = ConvertDeclSpecToType(DS, D.getIdentifierLoc(), isInvalid, SourceTy); + T = ConvertDeclSpecToType(DS, D.getIdentifierLoc(), isInvalid); if (isInvalid) D.setInvalidType(true); else if (OwnedDecl && DS.isTypeSpecOwned()) @@ -891,9 +875,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, break; } - if (SourceTy.isNull()) - SourceTy = T; - if (T == Context.UndeducedAutoTy) { int Error = -1; @@ -942,8 +923,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, if (D.getIdentifier()) Name = D.getIdentifier(); - bool ShouldBuildInfo = DInfo != 0; - // Walk the DeclTypeInfo, building the recursive type as we go. // DeclTypeInfos are ordered from the identifier out, which is // opposite of what we want :). @@ -952,17 +931,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, switch (DeclType.Kind) { default: assert(0 && "Unknown decltype!"); case DeclaratorChunk::BlockPointer: - if (ShouldBuildInfo) { - if (SourceTy->isFunctionType()) - SourceTy - = Context.getQualifiedType(Context.getBlockPointerType(SourceTy), - Qualifiers::fromCVRMask(DeclType.Cls.TypeQuals)); - else - // If not function type Context::getBlockPointerType asserts, - // so just give up. - ShouldBuildInfo = false; - } - // If blocks are disabled, emit an error. if (!LangOpts.Blocks) Diag(DeclType.Loc, diag::err_blocks_disable); @@ -971,10 +939,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, Name); break; case DeclaratorChunk::Pointer: - //FIXME: Use ObjCObjectPointer for info when appropriate. - if (ShouldBuildInfo) - SourceTy = Context.getQualifiedType(Context.getPointerType(SourceTy), - Qualifiers::fromCVRMask(DeclType.Ptr.TypeQuals)); // Verify that we're not building a pointer to pointer to function with // exception specification. if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { @@ -995,14 +959,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, Qualifiers Quals; if (DeclType.Ref.HasRestrict) Quals.addRestrict(); - if (ShouldBuildInfo) { - if (DeclType.Ref.LValueRef) - SourceTy = Context.getLValueReferenceType(SourceTy); - else - SourceTy = Context.getRValueReferenceType(SourceTy); - SourceTy = Context.getQualifiedType(SourceTy, Quals); - } - // Verify that we're not building a reference to pointer to function with // exception specification. if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { @@ -1015,11 +971,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, break; } case DeclaratorChunk::Array: { - if (ShouldBuildInfo) - // We just need to get an array type, the exact type doesn't matter. - SourceTy = Context.getIncompleteArrayType(SourceTy, ArrayType::Normal, - DeclType.Arr.TypeQuals); - // Verify that we're not building an array of pointers to function with // exception specification. if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { @@ -1051,24 +1002,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, break; } case DeclaratorChunk::Function: { - if (ShouldBuildInfo) { - const DeclaratorChunk:: |