diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 50 | ||||
-rw-r--r-- | clang/lib/AST/ASTDiagnostic.cpp | 5 | ||||
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 5 | ||||
-rw-r--r-- | clang/lib/AST/Comment.cpp | 5 | ||||
-rw-r--r-- | clang/lib/AST/Decl.cpp | 7 | ||||
-rw-r--r-- | clang/lib/AST/DeclPrinter.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 1 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 14 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 27 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 19 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 9 |
15 files changed, 131 insertions, 39 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0528a58f894..79b8770e0b7 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1632,8 +1632,9 @@ ASTContext::getTypeInfoImpl(const Type *T) const { } case Type::ObjCObject: return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr()); + case Type::Adjusted: case Type::Decayed: - return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr()); + return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr()); case Type::ObjCInterface: { const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T); const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); @@ -2163,14 +2164,29 @@ QualType ASTContext::getPointerType(QualType T) const { return QualType(New, 0); } -QualType ASTContext::getDecayedType(QualType T) const { - assert((T->isArrayType() || T->isFunctionType()) && "T does not decay"); - +QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const { llvm::FoldingSetNodeID ID; - DecayedType::Profile(ID, T); + AdjustedType::Profile(ID, Orig, New); void *InsertPos = 0; - if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos)) - return QualType(DT, 0); + AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); + if (AT) + return QualType(AT, 0); + + QualType Canonical = getCanonicalType(New); + + // Get the new insert position for the node we care about. + AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); + assert(AT == 0 && "Shouldn't be in the map!"); + + AT = new (*this, TypeAlignment) + AdjustedType(Type::Adjusted, Orig, New, Canonical); + Types.push_back(AT); + AdjustedTypes.InsertNode(AT, InsertPos); + return QualType(AT, 0); +} + +QualType ASTContext::getDecayedType(QualType T) const { + assert((T->isArrayType() || T->isFunctionType()) && "T does not decay"); QualType Decayed; @@ -2189,17 +2205,23 @@ QualType ASTContext::getDecayedType(QualType T) const { if (T->isFunctionType()) Decayed = getPointerType(T); + llvm::FoldingSetNodeID ID; + AdjustedType::Profile(ID, T, Decayed); + void *InsertPos = 0; + AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); + if (AT) + return QualType(AT, 0); + QualType Canonical = getCanonicalType(Decayed); // Get the new insert position for the node we care about. - DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); + assert(AT == 0 && "Shouldn't be in the map!"); - DecayedType *New = - new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical); - Types.push_back(New); - DecayedTypes.InsertNode(New, InsertPos); - return QualType(New, 0); + AT = new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical); + Types.push_back(AT); + AdjustedTypes.InsertNode(AT, InsertPos); + return QualType(AT, 0); } /// getBlockPointerType - Return the uniqued reference to the type for diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index ff1aea8a98a..7f7221fc6ed 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -51,6 +51,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) { QT = AT->desugar(); continue; } + // ...or an adjusted type... + if (const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) { + QT = AT->desugar(); + continue; + } // ... or an auto type. if (const AutoType *AT = dyn_cast<AutoType>(Ty)) { if (!AT->isSugared()) diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index e16015b7c4e..4292d358164 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -407,10 +407,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, return false; break; + case Type::Adjusted: case Type::Decayed: if (!IsStructurallyEquivalent(Context, - cast<DecayedType>(T1)->getPointeeType(), - cast<DecayedType>(T2)->getPointeeType())) + cast<AdjustedType>(T1)->getOriginalType(), + cast<AdjustedType>(T2)->getOriginalType())) return false; break; diff --git a/clang/lib/AST/Comment.cpp b/clang/lib/AST/Comment.cpp index f24a23d34c5..e60eed9630c 100644 --- a/clang/lib/AST/Comment.cpp +++ b/clang/lib/AST/Comment.cpp @@ -251,6 +251,11 @@ void DeclInfo::fill() { TL = PointerTL.getPointeeLoc().getUnqualifiedLoc(); continue; } + // Look through adjusted types. + if (AdjustedTypeLoc ATL = TL.getAs<AdjustedTypeLoc>()) { + TL = ATL.getOriginalLoc(); + continue; + } if (BlockPointerTypeLoc BlockPointerTL = TL.getAs<BlockPointerTypeLoc>()) { TL = BlockPointerTL.getPointeeLoc().getUnqualifiedLoc(); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index db3ab9536eb..c75cf20eb38 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2508,11 +2508,8 @@ unsigned FunctionDecl::getBuiltinID() const { /// based on its FunctionType. This is the length of the ParamInfo array /// after it has been created. unsigned FunctionDecl::getNumParams() const { - const FunctionType *FT = getType()->castAs<FunctionType>(); - if (isa<FunctionNoProtoType>(FT)) - return 0; - return cast<FunctionProtoType>(FT)->getNumArgs(); - + const FunctionProtoType *FPT = getType()->getAs<FunctionProtoType>(); + return FPT ? FPT->getNumArgs() : 0; } void FunctionDecl::setParams(ASTContext &C, diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 767f6620a29..f024f4593ba 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -423,8 +423,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { Ty = PT->getInnerType(); } - if (isa<FunctionType>(Ty)) { - const FunctionType *AFT = Ty->getAs<FunctionType>(); + if (const FunctionType *AFT = Ty->getAs<FunctionType>()) { const FunctionProtoType *FT = 0; if (D->hasWrittenPrototype()) FT = dyn_cast<FunctionProtoType>(AFT); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index ba67fad6489..e2d334b316d 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -833,6 +833,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, switch (type->getTypeClass()) { case Type::Builtin: case Type::Complex: + case Type::Adjusted: case Type::Decayed: case Type::Pointer: case Type::BlockPointer: diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 7421bae7bf5..cbb8bc61313 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -593,6 +593,9 @@ namespace { AutoType *VisitAttributedType(const AttributedType *T) { return Visit(T->getModifiedType()); } + AutoType *VisitAdjustedType(const AdjustedType *T) { + return Visit(T->getOriginalType()); + } }; } diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 571e3db0289..082d027791f 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -204,6 +204,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T, NeedARCStrongQualifier = true; // Fall through + case Type::Adjusted: case Type::Decayed: case Type::Pointer: case Type::BlockPointer: @@ -471,12 +472,21 @@ void TypePrinter::printVariableArrayAfter(const VariableArrayType *T, printAfter(T->getElementType(), OS); } +void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) { + // Print the adjusted representation, otherwise the adjustment will be + // invisible. + printBefore(T->getAdjustedType(), OS); +} +void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) { + printAfter(T->getAdjustedType(), OS); +} + void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) { // Print as though it's a pointer. - printBefore(T->getDecayedType(), OS); + printAdjustedBefore(T, OS); } void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) { - printAfter(T->getDecayedType(), OS); + printAdjustedAfter(T, OS); } void TypePrinter::printDependentSizedArrayBefore( diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index fcb26f0da61..451a6848baf 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2123,10 +2123,11 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) { return CreateType(cast<ComplexType>(Ty)); case Type::Pointer: return CreateType(cast<PointerType>(Ty), Unit); + case Type::Adjusted: case Type::Decayed: - // Decayed types are just pointers in LLVM and DWARF. + // Decayed and adjusted types use the adjusted type in LLVM and DWARF. return CreateType( - cast<PointerType>(cast<DecayedType>(Ty)->getDecayedType()), Unit); + cast<PointerType>(cast<AdjustedType>(Ty)->getAdjustedType()), Unit); case Type::BlockPointer: return CreateType(cast<BlockPointerType>(Ty), Unit); case Type::Typedef: diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index c1dc0b3657f..ce2c9b05c47 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1308,6 +1308,10 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { case Type::ObjCObjectPointer: llvm_unreachable("type class is never variably-modified!"); + case Type::Adjusted: + type = cast<AdjustedType>(ty)->getAdjustedType(); + break; + case Type::Decayed: type = cast<DecayedType>(ty)->getPointeeType(); break; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index dd28bfcf7d2..63ac15baeb6 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1812,7 +1812,10 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, } } - // FIXME: Adjust member function pointer calling conventions. + // Adjust the default free function calling convention to the default method + // calling convention. + if (T->isFunctionType()) + adjustMemberFunctionCC(T, /*IsStatic=*/false); return Context.getMemberPointerType(T, Class.getTypePtr()); } @@ -3681,6 +3684,9 @@ namespace { void VisitAttributedTypeLoc(AttributedTypeLoc TL) { fillAttributedTypeLoc(TL, Chunk.getAttrs()); } + void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { + // nothing + } void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { assert(Chunk.Kind == DeclaratorChunk::BlockPointer); TL.setCaretLoc(Chunk.Loc); @@ -3836,6 +3842,10 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); } + // FIXME: Ordering here? + while (AdjustedTypeLoc TL = CurrTL.getAs<AdjustedTypeLoc>()) + CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); + DeclaratorLocFiller(Context, D.getTypeObject(i)).Visit(CurrTL); CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc(); } @@ -4589,14 +4599,15 @@ void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic) { const FunctionType *FT = T->castAs<FunctionType>(); bool IsVariadic = (isa<FunctionProtoType>(FT) && cast<FunctionProtoType>(FT)->isVariadic()); - CallingConv CC = FT->getCallConv(); // Only adjust types with the default convention. For example, on Windows we // should adjust a __cdecl type to __thiscall for instance methods, and a // __thiscall type to __cdecl for static methods. - CallingConv DefaultCC = + CallingConv CurCC = FT->getCallConv(); + CallingConv FromCC = Context.getDefaultCallingConvention(IsVariadic, IsStatic); - if (CC != DefaultCC) + CallingConv ToCC = Context.getDefaultCallingConvention(IsVariadic, !IsStatic); + if (CurCC != FromCC || FromCC == ToCC) return; // Check if there was an explicit attribute, but only look through parens. @@ -4609,12 +4620,8 @@ void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic) { R = AT->getModifiedType().IgnoreParens(); } - // FIXME: This loses sugar. This should probably be fixed with an implicit - // AttributedType node that adjusts the convention. - CC = Context.getDefaultCallingConvention(IsVariadic, !IsStatic); - FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(CC)); - FunctionTypeUnwrapper Unwrapped(*this, T); - T = Unwrapped.wrap(*this, FT); + FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(ToCC)); + T = Context.getAdjustedType(T, QualType(FT, T.getQualifiers())); } /// Handle OpenCL image access qualifiers: read_only, write_only, read_write diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 44581fd4153..e9cb95006fe 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -3664,6 +3664,13 @@ QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB, return TransformTypeSpecType(TLB, T); } +template <typename Derived> +QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB, + AdjustedTypeLoc TL) { + // Adjustments applied during transformation are handled elsewhere. + return getDerived().TransformType(TLB, TL.getOriginalLoc()); +} + template<typename Derived> QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB, DecayedTypeLoc TL) { @@ -3832,6 +3839,14 @@ TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB, return QualType(); } + // If we had to adjust the pointee type when building a member pointer, make + // sure to push TypeLoc info for it. + const MemberPointerType *MPT = Result->getAs<MemberPointerType>(); + if (MPT && PointeeType != MPT->getPointeeType()) { + assert(isa<AdjustedType>(MPT->getPointeeType())); + TLB.push<AdjustedTypeLoc>(MPT->getPointeeType()); + } + MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result); NewTL.setSigilLoc(TL.getSigilLoc()); NewTL.setClassTInfo(NewClsTInfo); @@ -9391,8 +9406,8 @@ QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType, QualType ClassType, SourceLocation Sigil) { - return SemaRef.BuildMemberPointerType(PointeeType, ClassType, - Sigil, getDerived().getBaseEntity()); + return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil, + getDerived().getBaseEntity()); } template<typename Derived> diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 4d1b4b90b66..c531134a974 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -4548,6 +4548,16 @@ QualType ASTReader::readTypeRecord(unsigned Index) { return DT; } + case TYPE_ADJUSTED: { + if (Record.size() != 2) { + Error("Incorrect encoding of adjusted type"); + return QualType(); + } + QualType OriginalTy = readType(*Loc.F, Record, Idx); + QualType AdjustedTy = readType(*Loc.F, Record, Idx); + return Context.getAdjustedType(OriginalTy, AdjustedTy); + } + case TYPE_BLOCK_POINTER: { if (Record.size() != 1) { Error("Incorrect encoding of block pointer type"); @@ -4997,6 +5007,9 @@ void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) { void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) { // nothing to do } +void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { + // nothing to do +} void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { TL.setCaretLoc(ReadSourceLocation(Record, Idx)); } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index fa5b83d98fb..d8f170fd517 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -113,6 +113,12 @@ void ASTTypeWriter::VisitDecayedType(const DecayedType *T) { Code = TYPE_DECAYED; } +void ASTTypeWriter::VisitAdjustedType(const AdjustedType *T) { + Writer.AddTypeRef(T->getOriginalType(), Record); + Writer.AddTypeRef(T->getAdjustedType(), Record); + Code = TYPE_ADJUSTED; +} + void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) { Writer.AddTypeRef(T->getPointeeType(), Record); Code = TYPE_BLOCK_POINTER; @@ -455,6 +461,9 @@ void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) { void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) { // nothing to do } +void TypeLocWriter::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { + // nothing to do +} void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { Writer.AddSourceLocation(TL.getCaretLoc(), Record); } |