summaryrefslogtreecommitdiffstats
path: root/lib/AST
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-10-23 14:22:18 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-10-23 14:22:18 +0000
commit5563df30b9c8d1fe87a54baae0d6bd86642563f4 (patch)
tree3fdd91eae574e32453a4baf462961c742df2691a /lib/AST
parente5557c18e5d41b4b62f2af8a24af20eba40b0225 (diff)
downloadFreeBSD-src-5563df30b9c8d1fe87a54baae0d6bd86642563f4.zip
FreeBSD-src-5563df30b9c8d1fe87a54baae0d6bd86642563f4.tar.gz
Update clang to r84949.
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTContext.cpp507
-rw-r--r--lib/AST/CXXInheritance.cpp2
-rw-r--r--lib/AST/Decl.cpp53
-rw-r--r--lib/AST/DeclTemplate.cpp2
-rw-r--r--lib/AST/DeclarationName.cpp4
-rw-r--r--lib/AST/Expr.cpp50
-rw-r--r--lib/AST/Stmt.cpp2
-rw-r--r--lib/AST/StmtDumper.cpp8
-rw-r--r--lib/AST/StmtPrinter.cpp2
-rw-r--r--lib/AST/Type.cpp91
-rw-r--r--lib/AST/TypeLoc.cpp207
11 files changed, 519 insertions, 409 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e028186..7f5fa35 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -40,7 +40,8 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
bool FreeMem, unsigned size_reserve) :
GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0),
ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), jmp_bufDecl(0),
- sigjmp_bufDecl(0), SourceMgr(SM), LangOpts(LOpts),
+ sigjmp_bufDecl(0), BlockDescriptorType(0), BlockDescriptorExtendedType(0),
+ SourceMgr(SM), LangOpts(LOpts),
LoadedExternalComments(false), FreeMemory(FreeMem), Target(t),
Idents(idents), Selectors(sels),
BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) {
@@ -554,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
@@ -571,8 +568,6 @@ ASTContext::getTypeInfo(const Type *T) {
Align = getTypeAlign(cast<ArrayType>(T)->getElementType());
break;
- case Type::ConstantArrayWithExpr:
- case Type::ConstantArrayWithoutExpr:
case Type::ConstantArray: {
const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
@@ -583,14 +578,16 @@ ASTContext::getTypeInfo(const Type *T) {
}
case Type::ExtVector:
case Type::Vector: {
- std::pair<uint64_t, unsigned> EltInfo =
- getTypeInfo(cast<VectorType>(T)->getElementType());
- Width = EltInfo.first*cast<VectorType>(T)->getNumElements();
+ const VectorType *VT = cast<VectorType>(T);
+ std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(VT->getElementType());
+ Width = EltInfo.first*VT->getNumElements();
Align = Width;
// If the alignment is not a power of 2, round up to the next power of 2.
// This happens for non-power-of-2 length vectors.
- // FIXME: this should probably be a target property.
- Align = 1 << llvm::Log2_32_Ceil(Align);
+ if (VT->getNumElements() & (VT->getNumElements()-1)) {
+ Align = llvm::NextPowerOf2(Align);
+ Width = llvm::RoundUpToAlignment(Width, Align);
+ }
break;
}
@@ -749,9 +746,13 @@ ASTContext::getTypeInfo(const Type *T) {
break;
}
- case Type::Elaborated: {
- return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType().getTypePtr());
- }
+ case Type::SubstTemplateTypeParm:
+ return getTypeInfo(cast<SubstTemplateTypeParmType>(T)->
+ getReplacementType().getTypePtr());
+
+ case Type::Elaborated:
+ return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType()
+ .getTypePtr());
case Type::Typedef: {
const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
@@ -940,8 +941,14 @@ void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,
/// \param T the type that will be the basis for type source info. This type
/// should refer to how the declarator was written in source code, not to
/// what type semantic analysis resolved the declarator to.
-DeclaratorInfo *ASTContext::CreateDeclaratorInfo(QualType T) {
- unsigned DataSize = TypeLoc::getFullDataSizeForType(T);
+DeclaratorInfo *ASTContext::CreateDeclaratorInfo(QualType T,
+ unsigned DataSize) {
+ if (!DataSize)
+ DataSize = TypeLoc::getFullDataSizeForType(T);
+ else
+ assert(DataSize == TypeLoc::getFullDataSizeForType(T) &&
+ "incorrect data size provided to CreateDeclaratorInfo!");
+
DeclaratorInfo *DInfo =
(DeclaratorInfo*)BumpAlloc.Allocate(sizeof(DeclaratorInfo) + DataSize, 8);
new (DInfo) DeclaratorInfo(T);
@@ -1140,7 +1147,7 @@ QualType ASTContext::getComplexType(QualType T) {
// If the pointee type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field.
QualType Canonical;
- if (!T->isCanonical()) {
+ if (!T.isCanonical()) {
Canonical = getComplexType(getCanonicalType(T));
// Get the new insert position for the node we care about.
@@ -1177,7 +1184,7 @@ QualType ASTContext::getPointerType(QualType T) {
// If the pointee type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field.
QualType Canonical;
- if (!T->isCanonical()) {
+ if (!T.isCanonical()) {
Canonical = getPointerType(getCanonicalType(T));
// Get the new insert position for the node we care about.
@@ -1207,7 +1214,7 @@ QualType ASTContext::getBlockPointerType(QualType T) {
// If the block pointee type isn't canonical, this won't be a canonical
// type either so fill in the canonical type field.
QualType Canonical;
- if (!T->isCanonical()) {
+ if (!T.isCanonical()) {
Canonical = getBlockPointerType(getCanonicalType(T));
// Get the new insert position for the node we care about.
@@ -1224,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 =
@@ -1248,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);
}
@@ -1260,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 =
@@ -1302,7 +1317,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) {
// If the pointee or class type isn't canonical, this won't be a canonical
// type either, so fill in the canonical type field.
QualType Canonical;
- if (!T->isCanonical()) {
+ if (!T.isCanonical()) {
Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
// Get the new insert position for the node we care about.
@@ -1342,7 +1357,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
// If the element type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field.
QualType Canonical;
- if (!EltTy->isCanonical()) {
+ if (!EltTy.isCanonical()) {
Canonical = getConstantArrayType(getCanonicalType(EltTy), ArySize,
ASM, EltTypeQuals);
// Get the new insert position for the node we care about.
@@ -1358,53 +1373,6 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
return QualType(New, 0);
}
-/// getConstantArrayWithExprType - Return a reference to the type for
-/// an array of the specified element type.
-QualType
-ASTContext::getConstantArrayWithExprType(QualType EltTy,
- const llvm::APInt &ArySizeIn,
- Expr *ArySizeExpr,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals,
- SourceRange Brackets) {
- // Convert the array size into a canonical width matching the pointer
- // size for the target.
- llvm::APInt ArySize(ArySizeIn);
- ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace()));
-
- // Compute the canonical ConstantArrayType.
- QualType Canonical = getConstantArrayType(getCanonicalType(EltTy),
- ArySize, ASM, EltTypeQuals);
- // Since we don't unique expressions, it isn't possible to unique VLA's
- // that have an expression provided for their size.
- ConstantArrayWithExprType *New = new(*this, TypeAlignment)
- ConstantArrayWithExprType(EltTy, Canonical, ArySize, ArySizeExpr,
- ASM, EltTypeQuals, Brackets);
- Types.push_back(New);
- return QualType(New, 0);
-}
-
-/// getConstantArrayWithoutExprType - Return a reference to the type for
-/// an array of the specified element type.
-QualType
-ASTContext::getConstantArrayWithoutExprType(QualType EltTy,
- const llvm::APInt &ArySizeIn,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals) {
- // Convert the array size into a canonical width matching the pointer
- // size for the target.
- llvm::APInt ArySize(ArySizeIn);
- ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace()));
-
- // Compute the canonical ConstantArrayType.
- QualType Canonical = getConstantArrayType(getCanonicalType(EltTy),
- ArySize, ASM, EltTypeQuals);
- ConstantArrayWithoutExprType *New = new(*this, TypeAlignment)
- ConstantArrayWithoutExprType(EltTy, Canonical, ArySize, ASM, EltTypeQuals);
- Types.push_back(New);
- return QualType(New, 0);
-}
-
/// getVariableArrayType - Returns a non-unique reference to the type for a
/// variable array of the specified element type.
QualType ASTContext::getVariableArrayType(QualType EltTy,
@@ -1484,7 +1452,7 @@ QualType ASTContext::getIncompleteArrayType(QualType EltTy,
// either, so fill in the canonical type field.
QualType Canonical;
- if (!EltTy->isCanonical()) {
+ if (!EltTy.isCanonical()) {
Canonical = getIncompleteArrayType(getCanonicalType(EltTy),
ASM, EltTypeQuals);
@@ -1520,7 +1488,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
// If the element type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field.
QualType Canonical;
- if (!vecType->isCanonical()) {
+ if (!vecType.isCanonical()) {
Canonical = getVectorType(getCanonicalType(vecType), NumElts);
// Get the new insert position for the node we care about.
@@ -1552,7 +1520,7 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) {
// If the element type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field.
QualType Canonical;
- if (!vecType->isCanonical()) {
+ if (!vecType.isCanonical()) {
Canonical = getExtVectorType(getCanonicalType(vecType), NumElts);
// Get the new insert position for the node we care about.
@@ -1616,7 +1584,7 @@ QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn) {
return QualType(FT, 0);
QualType Canonical;
- if (!ResultTy->isCanonical()) {
+ if (!ResultTy.isCanonical()) {
Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn);
// Get the new insert position for the node we care about.
@@ -1639,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;
@@ -1658,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.
@@ -1672,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,
@@ -1743,6 +1703,29 @@ QualType ASTContext::getTypedefType(TypedefDecl *Decl) {
return QualType(Decl->TypeForDecl, 0);
}
+/// \brief Retrieve a substitution-result type.
+QualType
+ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
+ QualType Replacement) {
+ assert(Replacement.isCanonical()
+ && "replacement types must always be canonical");
+
+ llvm::FoldingSetNodeID ID;
+ SubstTemplateTypeParmType::Profile(ID, Parm, Replacement);
+ void *InsertPos = 0;
+ SubstTemplateTypeParmType *SubstParm
+ = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
+
+ if (!SubstParm) {
+ SubstParm = new (*this, TypeAlignment)
+ SubstTemplateTypeParmType(Parm, Replacement);
+ Types.push_back(SubstParm);
+ SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);
+ }
+
+ return QualType(SubstParm, 0);
+}
+
/// \brief Retrieve the template type parameter type for a template
/// parameter or parameter pack with the given depth, index, and (optionally)
/// name.
@@ -1933,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;
@@ -1950,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);
@@ -1962,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);
@@ -1975,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);
@@ -1987,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);
}
@@ -2168,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
@@ -2512,7 +2532,7 @@ int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) {
/// routine will assert if passed a built-in type that isn't an integer or enum,
/// or if it is not canonicalized.
unsigned ASTContext::getIntegerRank(Type *T) {
- assert(T->isCanonical() && "T should be canonicalized");
+ assert(T->isCanonicalUnqualified() && "T should be canonicalized");
if (EnumType* ET = dyn_cast<EnumType>(T))
T = ET->getDecl()->getIntegerType().getTypePtr();
@@ -2713,6 +2733,226 @@ QualType ASTContext::getObjCFastEnumerationStateType() {
return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
}
+QualType ASTContext::getBlockDescriptorType() {
+ if (BlockDescriptorType)
+ return getTagDeclType(BlockDescriptorType);
+
+ RecordDecl *T;
+ // FIXME: Needs the FlagAppleBlock bit.
+ T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get("__block_descriptor"));
+
+ QualType FieldTypes[] = {
+ UnsignedLongTy,
+ UnsignedLongTy,
+ };
+
+ const char *FieldNames[] = {
+ "reserved",
+ "Size"
+ };
+
+ for (size_t i = 0; i < 2; ++i) {
+ FieldDecl *Field = FieldDecl::Create(*this,
+ T,
+ SourceLocation(),
+ &Idents.get(FieldNames[i]),
+ FieldTypes[i], /*DInfo=*/0,
+ /*BitWidth=*/0,
+ /*Mutable=*/false);
+ T->addDecl(Field);
+ }
+
+ T->completeDefinition(*this);
+
+ BlockDescriptorType = T;
+
+ return getTagDeclType(BlockDescriptorType);
+}
+
+void ASTContext::setBlockDescriptorType(QualType T) {
+ const RecordType *Rec = T->getAs<RecordType>();
+ assert(Rec && "Invalid BlockDescriptorType");
+ BlockDescriptorType = Rec->getDecl();
+}
+
+QualType ASTContext::getBlockDescriptorExtendedType() {
+ if (BlockDescriptorExtendedType)
+ return getTagDeclType(BlockDescriptorExtendedType);
+
+ RecordDecl *T;
+ // FIXME: Needs the FlagAppleBlock bit.
+ T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get("__block_descriptor_withcopydispose"));
+
+ QualType FieldTypes[] = {
+ UnsignedLongTy,
+ UnsignedLongTy,
+ getPointerType(VoidPtrTy),
+ getPointerType(VoidPtrTy)
+ };
+
+ const char *FieldNames[] = {
+ "reserved",
+ "Size",
+ "CopyFuncPtr",
+ "DestroyFuncPtr"
+ };
+
+ for (size_t i = 0; i < 4; ++i) {
+ FieldDecl *Field = FieldDecl::Create(*this,
+ T,
+ SourceLocation(),
+ &Idents.get(FieldNames[i]),
+ FieldTypes[i], /*DInfo=*/0,
+ /*BitWidth=*/0,
+ /*Mutable=*/false);
+ T->addDecl(Field);
+ }
+
+ T->completeDefinition(*this);
+
+ BlockDescriptorExtendedType = T;
+
+ return getTagDeclType(BlockDescriptorExtendedType);
+}
+
+void ASTContext::setBlockDescriptorExtendedType(QualType T) {
+ const RecordType *Rec = T->getAs<RecordType>();
+ assert(Rec && "Invalid BlockDescriptorType");
+ BlockDescriptorExtendedType = Rec->getDecl();
+}
+
+bool ASTContext::BlockRequiresCopying(QualType Ty) {
+ if (Ty->isBlockPointerType())
+ return true;
+ if (isObjCNSObjectType(Ty))
+ return true;
+ if (Ty->isObjCObjectPointerType())
+ return true;
+ return false;
+}
+
+QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) {
+ // type = struct __Block_byref_1_X {
+ // void *__isa;
+ // struct __Block_byref_1_X *__forwarding;
+ // unsigned int __flags;
+ // unsigned int __size;
+ // void *__copy_helper; // as needed
+ // void *__destroy_help // as needed
+ // int X;
+ // } *
+
+ bool HasCopyAndDispose = BlockRequiresCopying(Ty);
+
+ // FIXME: Move up
+ static int UniqueBlockByRefTypeID = 0;
+ char Name[36];
+ sprintf(Name, "__Block_byref_%d_%s", ++UniqueBlockByRefTypeID, DeclName);
+ RecordDecl *T;
+ T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get(Name));
+ T->startDefinition();
+ QualType Int32Ty = IntTy;
+ assert(getIntWidth(IntTy) == 32 && "non-32bit int not supported");
+ QualType FieldTypes[] = {
+ getPointerType(VoidPtrTy),
+ getPointerType(getTagDeclType(T)),
+ Int32Ty,
+ Int32Ty,
+ getPointerType(VoidPtrTy),
+ getPointerType(VoidPtrTy),
+ Ty
+ };
+
+ const char *FieldNames[] = {
+ "__isa",
+ "__forwarding",
+ "__flags",
+ "__size",
+ "__copy_helper",
+ "__destroy_helper",
+ DeclName,
+ };
+
+ for (size_t i = 0; i < 7; ++i) {
+ if (!HasCopyAndDispose && i >=4 && i <= 5)
+ continue;
+ FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
+ &Idents.get(FieldNames[i]),
+ FieldTypes[i], /*DInfo=*/0,
+ /*BitWidth=*/0, /*Mutable=*/false);
+ T->addDecl(Field);
+ }
+
+ T->completeDefinition(*this);
+
+ return getPointerType(getTagDeclType(T));
+}
+
+
+QualType ASTContext::getBlockParmType(
+ bool BlockHasCopyDispose,
+ llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) {
+ // FIXME: Move up
+ static int UniqueBlockParmTypeID = 0;
+ char Name[36];
+ sprintf(Name, "__block_literal_%u", ++UniqueBlockParmTypeID);
+ RecordDecl *T;
+ T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get(Name));
+ QualType FieldTypes[] = {
+ getPointerType(VoidPtrTy),
+ IntTy,
+ IntTy,
+ getPointerType(VoidPtrTy),
+ (BlockHasCopyDispose ?
+ getPointerType(getBlockDescriptorExtendedType()) :
+ getPointerType(getBlockDescriptorType()))
+ };
+
+ const char *FieldNames[] = {
+ "__isa",
+ "__flags",
+ "__reserved",
+ "__FuncPtr",
+ "__descriptor"
+ };
+
+ for (size_t i = 0; i < 5; ++i) {
+ FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
+ &Idents.get(FieldNames[i]),
+ FieldTypes[i], /*DInfo=*/0,
+ /*BitWidth=*/0, /*Mutable=*/false);
+ T->addDecl(Field);
+ }
+
+ for (size_t i = 0; i < BlockDeclRefDecls.size(); ++i) {
+ const Expr *E = BlockDeclRefDecls[i];
+ const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
+ clang::IdentifierInfo *Name = 0;
+ if (BDRE) {
+ const ValueDecl *D = BDRE->getDecl();
+ Name = &Idents.get(D->getName());
+ }
+ QualType FieldType = E->getType();
+
+ if (BDRE && BDRE->isByRef())
+ FieldType = BuildByRefType(BDRE->getDecl()->getNameAsCString(),
+ FieldType);
+
+ FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
+ Name, FieldType, /*DInfo=*/0,
+ /*BitWidth=*/0, /*Mutable=*/false);
+ T->addDecl(Field);
+ }
+
+ T->completeDefinition(*this);
+
+ return getPointerType(getTagDeclType(T));
+}
+
void ASTContext::setObjCFastEnumerationStateType(QualType T) {
const RecordType *Rec = T->getAs<RecordType>();
assert(Rec && "Invalid ObjCFAstEnumerationStateType");
@@ -2945,6 +3185,7 @@ static void EncodeBitField(const ASTContext *Context, std::string& S,
S += llvm::utostr(N);
}
+// FIXME: Use SmallString for accumulating string.
void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
bool ExpandPointedToStructures,
bool ExpandStructures,
@@ -3420,7 +3661,7 @@ Qualifiers::GC ASTContext::getObjCGCAttrKind(const QualType &Ty) const {
/// compatible.
static bool areCompatVectorTypes(const VectorType *LHS,
const VectorType *RHS) {
- assert(LHS->isCanonical() && RHS->isCanonical());
+ assert(LHS->isCanonicalUnqualified() && RHS->isCanonicalUnqualified());
return LHS->getElementType() == RHS->getElementType() &&
LHS->getNumElements() == RHS->getNumElements();
}
@@ -3979,7 +4220,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
unsigned ASTContext::getIntWidth(QualType T) {
if (T == BoolTy)
return 1;
- if (FixedWidthIntType* FWIT = dyn_cast<FixedWidthIntType>(T)) {
+ if (FixedWidthIntType *FWIT = dyn_cast<FixedWidthIntType>(T)) {
return FWIT->getWidth();
}
// For builtin types, just use the standard type sizing method
@@ -3988,10 +4229,18 @@ unsigned ASTContext::getIntWidth(QualType T) {
QualType ASTContext::getCorrespondingUnsignedType(QualType T) {
assert(T->isSignedIntegerType() && "Unexpected type");
- if (const EnumType* ETy = T->getAs<EnumType>())
+
+ // Turn <4 x signed int> -> <4 x unsigned int>
+ if (const VectorType *VTy = T->getAs<VectorType>())
+ return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()),
+ VTy->getNumElements());
+
+ // For enums, we return the unsigned version of the base type.
+ if (const EnumType *ETy = T->getAs<EnumType>())
T = ETy->getDecl()->getIntegerType();
- const BuiltinType* BTy = T->getAs<BuiltinType>();
- assert (BTy && "Unexpected signed integer type");
+
+ const BuiltinType *BTy = T->getAs<BuiltinType>();
+ assert(BTy && "Unexpected signed integer type");
switch (BTy->getKind()) {
case BuiltinType::Char_S:
case BuiltinType::SChar:
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 4a46eab..b59b45f 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -50,7 +50,7 @@ CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() {
/// different base class subobjects of the same type. BaseType must be
/// an unqualified, canonical class type.
bool CXXBasePaths::isAmbiguous(QualType BaseType) {
- assert(BaseType->isCanonical() && "Base type must be the canonical type");
+ assert(BaseType.isCanonical() && "Base type must be the canonical type");
assert(BaseType.hasQualifiers() == 0 && "Base type must be unqualified");
std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
return Subobjects.second + (Subobjects.first? 1 : 0) > 1;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index da7959b..d270a95 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -231,6 +231,8 @@ std::string NamedDecl::getQualifiedNameAsString() const {
}
std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
+ // FIXME: Collect contexts, then accumulate names to avoid unnecessary
+ // std::string thrashing.
std::vector<std::string> Names;
std::string QualName;
const DeclContext *Ctx = getDeclContext();
@@ -252,7 +254,7 @@ std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
TemplateArgs.getFlatArgumentList(),
TemplateArgs.flat_size(),
P);
- Names.push_back(Spec->getIdentifier()->getName() + TemplateArgsStr);
+ Names.push_back(Spec->getIdentifier()->getNameStart() + TemplateArgsStr);
} else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
Names.push_back(ND->getNameAsString());
else
@@ -336,8 +338,15 @@ NamedDecl *NamedDecl::getUnderlyingDecl() {
//===----------------------------------------------------------------------===//
SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
- if (DeclInfo)
- return DeclInfo->getTypeLoc().getTypeSpecRange().getBegin();
+ if (DeclInfo) {
+ TypeLoc TL = DeclInfo->getTypeLoc();
+ while (true) {
+ TypeLoc NextTL = TL.getNextTypeLoc();
+ if (!NextTL)
+ return TL.getSourceRange().getBegin();
+ TL = NextTL;
+ }
+ }
return SourceLocation();
}
@@ -408,10 +417,15 @@ MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const {
return getASTContext().getInstantiatedFromStaticDataMember(this);
}
-void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
+void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+ SourceLocation PointOfInstantiation) {
MemberSpecializationInfo *MSI = getMemberSpecializationInfo();
assert(MSI && "Not an instantiated static data member?");
MSI->setTemplateSpecializationKind(TSK);
+ if (TSK != TSK_ExplicitSpecialization &&
+ PointOfInstantiation.isValid() &&
+ MSI->getPointOfInstantiation().isInvalid())
+ MSI->setPointOfInstantiation(PointOfInstantiation);
}
bool VarDecl::isTentativeDefinition(ASTContext &Context) const {
@@ -812,18 +826,39 @@ TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const {
}
void
-FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
+FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+ SourceLocation PointOfInstantiation) {
if (FunctionTemplateSpecializationInfo *FTSInfo
= TemplateOrSpecialization.dyn_cast<
- FunctionTemplateSpecializationInfo*>())
+ FunctionTemplateSpecializationInfo*>()) {
FTSInfo->setTemplateSpecializationKind(TSK);
- else if (MemberSpecializationInfo *MSInfo
- = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>())
+ if (TSK != TSK_ExplicitSpecialization &&
+ PointOfInstantiation.isValid() &&
+ FTSInfo->getPointOfInstantiation().isInvalid())
+ FTSInfo->setPointOfInstantiation(PointOfInstantiation);
+ } else if (MemberSpecializationInfo *MSInfo
+ = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) {
MSInfo->setTemplateSpecializationKind(TSK);
- else
+ if (TSK != TSK_ExplicitSpecialization &&
+ PointOfInstantiation.isValid() &&
+ MSInfo->getPointOfInstantiation().isInvalid())
+ MSInfo->setPointOfInstantiation(PointOfInstantiation);
+ } else
assert(false && "Function cannot have a template specialization kind");
}
+SourceLocation FunctionDecl::getPointOfInstantiation() const {
+ if (FunctionTemplateSpecializationInfo *FTSInfo
+ = TemplateOrSpecialization.dyn_cast<
+ FunctionTemplateSpecializationInfo*>())
+ return FTSInfo->getPointOfInstantiation();
+ else if (MemberSpecializationInfo *MSInfo
+ = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>())
+ return MSInfo->getPointOfInstantiation();
+
+ return SourceLocation();
+}
+
bool FunctionDecl::isOutOfLine() const {
if (Decl::isOutOfLine())
return true;
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 7836b3f..9a1c654 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -299,7 +299,7 @@ void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
switch (Arg.getKind()) {
default: break;
case TemplateArgument::Type:
- assert(Arg.getAsType()->isCanonical() && "Type must be canonical!");
+ assert(Arg.getAsType().isCanonical() && "Type must be canonical!");
break;
}
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 101ddd2..56a5975 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -51,7 +51,7 @@ public:
bool operator<(DeclarationName LHS, DeclarationName RHS) {
if (IdentifierInfo *LhsId = LHS.getAsIdentifierInfo())
if (IdentifierInfo *RhsId = RHS.getAsIdentifierInfo())
- return strcmp(LhsId->getName(), RhsId->getName()) < 0;
+ return LhsId->getName() < RhsId->getName();
return LHS.getAsOpaqueInteger() < RHS.getAsOpaqueInteger();
}
@@ -60,7 +60,7 @@ bool operator<(DeclarationName LHS, DeclarationName RHS) {
DeclarationName::DeclarationName(Selector Sel) {
if (!Sel.getAsOpaquePtr()) {
- Ptr = StoredObjCZeroArgSelector;
+ Ptr = 0;
return;
}
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 0e4a29f..a4de3e5 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -426,6 +426,18 @@ const char *CastExpr::getCastKindName() const {
return "IntegralToPointer";
case CastExpr::CK_PointerToIntegral:
return "PointerToIntegral";
+ case CastExpr::CK_ToVoid:
+ return "ToVoid";
+ case CastExpr::CK_VectorSplat:
+ return "VectorSplat";
+ case CastExpr::CK_IntegralCast:
+ return "IntegralCast";
+ case CastExpr::CK_IntegralToFloating:
+ return "IntegralToFloating";
+ case CastExpr::CK_FloatingToIntegral:
+ return "FloatingToIntegral";
+ case CastExpr::CK_FloatingCast:
+ return "FloatingCast";
}
assert(0 && "Unhandled cast kind!");
@@ -1740,40 +1752,36 @@ unsigned ExtVectorElementExpr::getNumElements() const {
/// containsDuplicateElements - Return true if any element access is repeated.
bool ExtVectorElementExpr::containsDuplicateElements() const {
- const char *compStr = Accessor->getName();
- unsigned length = Accessor->getLength();
+ // FIXME: Refactor this code to an accessor on the AST node which returns the
+ // "type" of component access, and share with code below and in Sema.
+ llvm::StringRef Comp = Accessor->getName();
// Halving swizzles do not contain duplicate elements.
- if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") ||
- !strcmp(compStr, "even") || !strcmp(compStr, "odd"))
+ if (Comp == "hi" || Comp == "lo" || Comp == "even" || Comp == "odd")
return false;
// Advance past s-char prefix on hex swizzles.
- if (*compStr == 's' || *compStr == 'S') {
- compStr++;
- length--;
- }
+ if (Comp[0] == 's' || Comp[0] == 'S')
+ Comp = Comp.substr(1);
- for (unsigned i = 0; i != length-1; i++) {
- const char *s = compStr+i;
- for (const char c = *s++; *s; s++)
- if (c == *s)
+ for (unsigned i = 0, e = Comp.size(); i != e; ++i)
+ if (Comp.substr(i + 1).find(Comp[i]) != llvm::StringRef::npos)
return true;
- }
+
return false;
}
/// getEncodedElementAccess - We encode the fields as a llvm ConstantArray.
void ExtVectorElementExpr::getEncodedElementAccess(
llvm::SmallVectorImpl<unsigned> &Elts) const {
- const char *compStr = Accessor->getName();
- if (*compStr == 's' || *compStr == 'S')
- compStr++;
+ llvm::StringRef Comp = Accessor->getName();
+ if (Comp[0] == 's' || Comp[0] == 'S')
+ Comp = Comp.substr(1);
- bool isHi = !strcmp(compStr, "hi");
- bool isLo = !strcmp(compStr, "lo");
- bool isEven = !strcmp(compStr, "even");
- bool isOdd = !strcmp(compStr, "odd");
+ bool isHi = Comp == "hi";
+ bool isLo = Comp == "lo";
+ bool isEven = Comp == "even";
+ bool isOdd = Comp == "odd";
for (unsigned i = 0, e = getNumElements(); i != e; ++i) {
uint64_t Index;
@@ -1787,7 +1795,7 @@ void ExtVectorElementExpr::getEncodedElementAccess(
else if (isOdd)
Index = 2 * i + 1;
else
- Index = ExtVectorType::getAccessorIdx(compStr[i]);
+ Index = ExtVectorType::getAccessorIdx(Comp[i]);
Elts.push_back(Index);
}
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 3a838fa..6e0da47 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -117,7 +117,7 @@ void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
}
const char *LabelStmt::getName() const {
- return getID()->getName();
+ return getID()->getNameStart();
}
// This is defined here to avoid polluting Stmt.h with importing Expr.h
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 0465999..cf71d6b 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -244,7 +244,7 @@ void StmtDumper::DumpDeclarator(Decl *D) {
// print a free standing tag decl (e.g. "struct x;").
const char *tagname;
if (const IdentifierInfo *II = TD->getIdentifier())
- tagname = II->getName();
+ tagname = II->getNameStart();
else
tagname = "<anonymous>";
fprintf(F, "\"%s %s;\"", TD->getKindName(), tagname);
@@ -253,7 +253,7 @@ void StmtDumper::DumpDeclarator(Decl *D) {
// print using-directive decl (e.g. "using namespace x;")
const char *ns;
if (const IdentifierInfo *II = UD->getNominatedNamespace()->getIdentifier())
- ns = II->getName();
+ ns = II->getNameStart();
else
ns = "<anonymous>";
fprintf(F, "\"%s %s;\"",UD->getDeclKindName(), ns);
@@ -403,7 +403,7 @@ void StmtDumper::VisitMemberExpr(MemberExpr *Node) {
}
void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
DumpExpr(Node);
- fprintf(F, " %s", Node->getAccessor().getName());
+ fprintf(F, " %s", Node->getAccessor().getNameStart());
}
void StmtDumper::VisitBinaryOperator(BinaryOperator *Node) {
DumpExpr(Node);
@@ -495,7 +495,7 @@ void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
DumpExpr(Node);
fprintf(F, " selector=%s", Node->getSelector().getAsString().c_str());
IdentifierInfo* clsName = Node->getClassName();
- if (clsName) fprintf(F, " class=%s", clsName->getName());
+ if (clsName) fprintf(F, " class=%s", clsName->getNameStart());
}
void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 05d0c26..2af1976 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1289,7 +1289,7 @@ void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
return;
}
- if (Policy.Dump) {
+ if (Policy.Dump && &Context) {
dump(Context.getSourceManager());
return;
}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 0293862..5fb0178 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -37,18 +37,6 @@ void Type::Destroy(ASTContext& C) {
C.Deallocate(this);
}
-void ConstantArrayWithExprType::Destroy(ASTContext& C) {
- // FIXME: destruction of SizeExpr commented out due to resource contention.
- // SizeExpr->Destroy(C);
- // See FIXME in SemaDecl.cpp:1536: if we were able to either steal
- // or clone the SizeExpr there, then here we could freely delete it.
- // Since we do not know how to steal or clone, we keep a pointer to
- // a shared resource, but we cannot free it.
- // (There probably is a trivial solution ... for people knowing clang!).
- this->~ConstantArrayWithExprType();
- C.Deallocate(this);
-}
-
void VariableArrayType::Destroy(ASTContext& C) {
if (SizeExpr)
SizeExpr->Destroy(C);
@@ -177,8 +165,6 @@ bool Type::isDerivedType() const {
case Pointer:
case VariableArray:
case ConstantArray:
- case ConstantArrayWithExpr:
- case ConstantArrayWithoutExpr:
case IncompleteArray:
case FunctionProto:
case FunctionNoProto:
@@ -642,6 +628,7 @@ bool Type::isSpecifierType() const {
case TypeOfExpr:
case TypeOf:
case TemplateTypeParm:
+ case SubstTemplateTypeParm:
case TemplateSpecialization:
case QualifiedName:
case Typename:
@@ -737,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:
@@ -1072,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 {
@@ -1083,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 {
@@ -1111,29 +1086,6 @@ void ConstantArrayType::getAsStringInternal(std::string &S, const PrintingPolicy
getElementType().getAsStringInternal(S, Policy);
}
-void ConstantArrayWithExprType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- if (Policy.ConstantArraySizeAsWritten) {
- std::string SStr;
- llvm::raw_string_ostream s(SStr);
- getSizeExpr()->printPretty(s, 0, Policy);
- S += '[';
- S += s.str();
- S += ']';
- getElementType().getAsStringInternal(S, Policy);
- }
- else
- ConstantArrayType::getAsStringInternal(S, Policy);
-}
-
-void ConstantArrayWithoutExprType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- if (Policy.ConstantArraySizeAsWritten) {
- S += "[]";
- getElementType().getAsStringInternal(S, Policy);
- }
- else
- ConstantArrayType::getAsStringInternal(S, Policy);
-}
-
void IncompleteArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
S += "[]";
@@ -1290,7 +1242,7 @@ void FunctionProtoType::getAsStringInternal(std::string &S, const PrintingPolicy
void TypedefType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
InnerString = ' ' + InnerString;
- InnerString = getDecl()->getIdentifier()->getName() + InnerString;
+ InnerString = getDecl()->getIdentifier()->getName().str() + InnerString;
}
void TemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
@@ -1301,7 +1253,11 @@ void TemplateTypeParmType::getAsStringInternal(std::string &InnerString, const P
InnerString = "type-parameter-" + llvm::utostr_32(Depth) + '-' +
llvm::utostr_32(Index) + InnerString;
else
- InnerString = Name->getName() + InnerString;
+ InnerString = Name->getName().str() + InnerString;
+}
+
+void SubstTemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
+ getReplacementType().getAsStringInternal(InnerString, Policy);
}
std::string
@@ -1495,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;
@@ -1534,11 +1471,11 @@ void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy
const char *Kind = Policy.SuppressTagKind? 0 : getDecl()->getKindName();
const char *ID;
if (const IdentifierInfo *II = getDecl()->getIdentifier())
- ID = II->getName();
+ ID = II->getNameStart();
else if (TypedefDecl *Typedef = getDecl()->getTypedefForAnonDecl()) {
Kind = 0;
assert(Typedef->getIdentifier() && "Typedef without identifier?");
- ID = Typedef->getIdentifier()->getName();
+ ID = Typedef->getIdentifier()->getNameStart();
} else
ID = "<anonymous>";
@@ -1573,7 +1510,7 @@ void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy
TemplateArgs.getFlatArgumentList(),
TemplateArgs.flat_size(),
Policy);
- MyPart = Spec->getIdentifier()->getName() + TemplateArgsStr;
+ MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr;
} else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
MyPart = Typedef->getIdentifier()->getName();
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index 04e7083..50a5120 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -20,55 +20,32 @@ using namespace clang;
//===----------------------------------------------------------------------===//
namespace {
-
-/// \brief Return the source range for the visited TypeSpecLoc.
-class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
-public:
-#define ABSTRACT_TYPELOC(CLASS)
+ class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
+ public:
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
- SourceRange Visit##CLASS(CLASS TyLoc) { return TyLoc.getSourceRange(); }
+ SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+ return TyLoc.getSourceRange(); \
+ }
#include "clang/AST/TypeLocNodes.def"
-
- SourceRange VisitTypeLoc(TypeLoc TyLoc) {
- assert(0 && "A typeloc wrapper was not handled!");
- return SourceRange();
- }
-};
-
-}
-
-SourceRange TypeLoc::getSourceRange() const {
- if (isNull())
- return SourceRange();
- return TypeLocRanger().Visit(*this);
+ };
}
-/// \brief Find the TypeSpecLoc that is part of this TypeLoc.
-TypeSpecLoc TypeLoc::getTypeSpecLoc() const {
- if (isNull())
- return TypeSpecLoc();
- UnqualTypeLoc Cur = getUnqualifiedLoc();
- if (const DeclaratorLoc *DL = dyn_cast<DeclaratorLoc>(&Cur))
- return DL->getTypeSpecLoc();
- return cast<TypeSpecLoc>(Cur);
+SourceRange TypeLoc::getSourceRangeImpl(TypeLoc TL) {
+ if (TL.isNull()) return SourceRange();
+ return TypeLocRanger().Visit(TL);
}
namespace {
-
-/// \brief Report the full source info data size for the visited TypeLoc.
-class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
-public:
-#define ABSTRACT_TYPELOC(CLASS)
+ class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
+ public:
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
- unsigned Visit##CLASS(CLASS TyLoc) { return TyLoc.getFullDataSize(); }
+ unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+ return TyLoc.getFullDataSize(); \
+ }
#include "clang/AST/TypeLocNodes.def"
-
- unsigned VisitTypeLoc(TypeLoc TyLoc) {
- assert(0 && "A type loc wrapper was not handled!");
- return 0;
- }
-};
-
+ };
}
/// \brief Returns the size of the type source info data block.
@@ -78,138 +55,42 @@ unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
}
namespace {
-
-/// \brief Return the "next" TypeLoc for the visited TypeLoc, e.g for "int*" the
-/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
-class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
-public:
-#define TYPELOC(CLASS, PARENT)
-#define DECLARATOR_TYPELOC(CLASS, TYPE) \
- TypeLoc Visit##CLASS(CLASS TyLoc);
+ class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
+ public:
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+ return TyLoc.getNextTypeLoc(); \
+ }
#include "clang/AST/TypeLocNodes.def"
-
- TypeLoc VisitTypeSpecLoc(TypeLoc TyLoc) { return TypeLoc(); }
- TypeLoc VisitObjCProtocolListLoc(ObjCProtocolListLoc TL);
- TypeLoc VisitQualifiedLoc(QualifiedLoc TyLoc) {
- return TyLoc.getUnqualifiedLoc();
- }
-
- TypeLoc VisitTypeLoc(TypeLoc TyLoc) {
- assert(0 && "A declarator loc wrapper was not handled!");
- return TypeLoc();
- }
-};
-
-}
-
-TypeLoc NextLoc::VisitObjCProtocolListLoc(ObjCProtocolListLoc TL) {
- return TL.getBaseTypeLoc();
-}
-
-TypeLoc NextLoc::VisitPointerLoc(PointerLoc TL) {
- return TL.getPointeeLoc();
-}
-TypeLoc NextLoc::VisitMemberPointerLoc(MemberPointerLoc TL) {
- return TL.getPointeeLoc();
-}
-TypeLoc NextLoc::VisitBlockPointerLoc(BlockPointerLoc TL) {
- return TL.getPointeeLoc();
-}
-TypeLoc NextLoc::VisitReferenceLoc(ReferenceLoc TL) {
- return TL.getPointeeLoc();
-}
-TypeLoc NextLoc::VisitFunctionLoc(FunctionLoc TL) {
- return TL.getResultLoc();
-}
-TypeLoc NextLoc::VisitArrayLoc(ArrayLoc TL) {
- return TL.getElementLoc();
+ };
}
/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
-TypeLoc TypeLoc::getNextTypeLoc() const {
- //llvm::errs() << "getNextTypeLoc: Ty=" << Ty << ", Data=" << Data << "\n";
- TypeLoc Tmp = NextLoc().Visit(*this);
- //llvm::errs() << " result: Ty=" << Tmp.Ty << ", Data=" << Tmp.Data << "\n";
- return Tmp;
+TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
+ return NextLoc().Visit(TL);
}
-//===----------------------------------------------------------------------===//
-// TypeSpecLoc Implementation
-//===----------------------------------------------------------------------===//
-
namespace {
-class TypeSpecChecker : public TypeLocVisitor<TypeSpecChecker, bool> {
-public:
- bool VisitTypeSpecLoc(TypeSpecLoc TyLoc) { return true; }
-};
-
-}
-
-bool TypeSpecLoc::classof(const UnqualTypeLoc *TL) {
- return TypeSpecChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// DeclaratorLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-/// \brief Return the TypeSpecLoc for the visited DeclaratorLoc.
-class TypeSpecGetter : public TypeLocVisitor<TypeSpecGetter, TypeSpecLoc> {
-public:
-#define TYPELOC(CLASS, PARENT)
-#define DECLARATOR_TYPELOC(CLASS, TYPE) \
- TypeSpecLoc Visit##CLASS(CLASS TyLoc) { return TyLoc.getTypeSpecLoc(); }
+ struct TypeLocInitializer : public TypeLocVisitor<TypeLocInitializer> {
+ SourceLocation Loc;
+ TypeLocInitializer(SourceLocation Loc) : Loc(Loc) {}
+
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+ TyLoc.initializeLocal(Loc); \
+ }
#include "clang/AST/TypeLocNodes.def"
-
- TypeSpecLoc VisitTypeLoc(TypeLoc TyLoc) {
- assert(0 && "A declarator loc wrapper was not handled!");
- return TypeSpecLoc();
- }
-
- TypeSpecLoc VisitQualifiedLoc(QualifiedLoc TyLoc) {
- return Visit(TyLoc.getUnqualifiedLoc());
- }
-};
-
-}
-
-/// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc.
-TypeSpecLoc DeclaratorLoc::getTypeSpecLoc() const {
- return TypeSpecGetter().Visit(*this);
-}
-
-namespace {
-
-class DeclaratorLocChecker : public TypeLocVisitor<DeclaratorLocChecker, bool> {
-public:
- bool VisitDeclaratorLoc(DeclaratorLoc TyLoc) { return true; }
-};
-
-}
-
-bool DeclaratorLoc::classof(const UnqualTypeLoc *TL) {
- return DeclaratorLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// DefaultTypeSpecLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class DefaultTypeSpecLocChecker :
- public TypeLocVisitor<DefaultTypeSpecLocChecker, bool> {
-public:
- bool VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { return true; }
-};
-
+ };
}
-bool DefaultTypeSpecLoc::classofType(const Type *Ty) {
- return
- DefaultTypeSpecLocChecker().Visit(UnqualTypeLoc(const_cast<Type*>(Ty), 0));
+/// \brief Initializes a type location, and all of its children
+/// recursively, as if the entire tree had been written in the
+/// given location.
+void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) {
+ do {
+ TypeLocInitializer(Loc).Visit(TL);
+ } while ((TL = TL.getNextTypeLoc()));
}
-
OpenPOWER on IntegriCloud