summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp50
-rw-r--r--clang/lib/AST/ASTDiagnostic.cpp5
-rw-r--r--clang/lib/AST/ASTImporter.cpp5
-rw-r--r--clang/lib/AST/Comment.cpp5
-rw-r--r--clang/lib/AST/Decl.cpp7
-rw-r--r--clang/lib/AST/DeclPrinter.cpp3
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp1
-rw-r--r--clang/lib/AST/Type.cpp3
-rw-r--r--clang/lib/AST/TypePrinter.cpp14
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp5
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp4
-rw-r--r--clang/lib/Sema/SemaType.cpp27
-rw-r--r--clang/lib/Sema/TreeTransform.h19
-rw-r--r--clang/lib/Serialization/ASTReader.cpp13
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp9
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);
}
OpenPOWER on IntegriCloud