diff options
| author | Reid Kleckner <reid@kleckner.net> | 2013-12-05 01:23:43 +0000 |
|---|---|---|
| committer | Reid Kleckner <reid@kleckner.net> | 2013-12-05 01:23:43 +0000 |
| commit | 0503a870a94c28ab32fa461e175f8cb387c8718e (patch) | |
| tree | fa28b29965ee5c660e774fb67830aa8fd3b73e57 /clang/lib/AST | |
| parent | d33ff74b196c38ff414773d39899514a9c9dd8ed (diff) | |
| download | bcm5719-llvm-0503a870a94c28ab32fa461e175f8cb387c8718e.tar.gz bcm5719-llvm-0503a870a94c28ab32fa461e175f8cb387c8718e.zip | |
Add an AdjustedType sugar node for adjusting calling conventions
Summary:
In general, this type node can be used to represent any type adjustment
that occurs implicitly without losing type sugar. The immediate use of
this is to adjust the calling conventions of member function pointer
types without breaking template instantiation.
Fixes PR17996.
Reviewers: rsmith
Differential Revision: http://llvm-reviews.chandlerc.com/D2332
llvm-svn: 196451
Diffstat (limited to 'clang/lib/AST')
| -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 |
9 files changed, 68 insertions, 25 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( |

