aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp141
-rw-r--r--lib/AST/Type.cpp39
-rw-r--r--lib/CodeGen/Mangle.cpp7
-rw-r--r--lib/Frontend/PCHReader.cpp23
-rw-r--r--lib/Frontend/PCHWriter.cpp23
-rw-r--r--lib/Index/ResolveLocation.cpp45
-rw-r--r--lib/Sema/Sema.h18
-rw-r--r--lib/Sema/SemaDeclCXX.cpp3
-rw-r--r--lib/Sema/SemaType.cpp205
-rw-r--r--lib/Sema/TreeTransform.h50
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::