summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r--lib/Sema/SemaType.cpp372
1 files changed, 184 insertions, 188 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 35efa6113b64..a4fc98cd958e 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -383,8 +383,12 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
} else if (DS.isTypeAltiVecVector()) {
unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(Result));
assert(typeSize > 0 && "type size for vector must be greater than 0 bits");
- Result = Context.getVectorType(Result, 128/typeSize, true,
- DS.isTypeAltiVecPixel());
+ VectorType::AltiVecSpecific AltiVecSpec = VectorType::AltiVec;
+ if (DS.isTypeAltiVecPixel())
+ AltiVecSpec = VectorType::Pixel;
+ else if (DS.isTypeAltiVecBool())
+ AltiVecSpec = VectorType::Bool;
+ Result = Context.getVectorType(Result, 128/typeSize, AltiVecSpec);
}
assert(DS.getTypeSpecComplex() != DeclSpec::TSC_imaginary &&
@@ -472,12 +476,49 @@ static std::string getPrintableNameForEntity(DeclarationName Entity) {
return "type name";
}
+QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc,
+ Qualifiers Qs) {
+ // Enforce C99 6.7.3p2: "Types other than pointer types derived from
+ // object or incomplete types shall not be restrict-qualified."
+ if (Qs.hasRestrict()) {
+ unsigned DiagID = 0;
+ QualType ProblemTy;
+
+ const Type *Ty = T->getCanonicalTypeInternal().getTypePtr();
+ if (const ReferenceType *RTy = dyn_cast<ReferenceType>(Ty)) {
+ if (!RTy->getPointeeType()->isIncompleteOrObjectType()) {
+ DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee;
+ ProblemTy = T->getAs<ReferenceType>()->getPointeeType();
+ }
+ } else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
+ if (!PTy->getPointeeType()->isIncompleteOrObjectType()) {
+ DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee;
+ ProblemTy = T->getAs<PointerType>()->getPointeeType();
+ }
+ } else if (const MemberPointerType *PTy = dyn_cast<MemberPointerType>(Ty)) {
+ if (!PTy->getPointeeType()->isIncompleteOrObjectType()) {
+ DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee;
+ ProblemTy = T->getAs<PointerType>()->getPointeeType();
+ }
+ } else if (!Ty->isDependentType()) {
+ // FIXME: this deserves a proper diagnostic
+ DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee;
+ ProblemTy = T;
+ }
+
+ if (DiagID) {
+ Diag(Loc, DiagID) << ProblemTy;
+ Qs.removeRestrict();
+ }
+ }
+
+ return Context.getQualifiedType(T, Qs);
+}
+
/// \brief Build a pointer type.
///
/// \param T The type to which we'll be building a pointer.
///
-/// \param Quals The cvr-qualifiers to be applied to the pointer type.
-///
/// \param Loc The location of the entity whose type involves this
/// pointer type or, if there is no such entity, the location of the
/// type that will have pointer type.
@@ -487,7 +528,7 @@ static std::string getPrintableNameForEntity(DeclarationName Entity) {
///
/// \returns A suitable pointer type, if there are no
/// errors. Otherwise, returns a NULL type.
-QualType Sema::BuildPointerType(QualType T, unsigned Quals,
+QualType Sema::BuildPointerType(QualType T,
SourceLocation Loc, DeclarationName Entity) {
if (T->isReferenceType()) {
// C++ 8.3.2p4: There shall be no ... pointers to references ...
@@ -496,28 +537,16 @@ QualType Sema::BuildPointerType(QualType T, unsigned Quals,
return QualType();
}
- Qualifiers Qs = Qualifiers::fromCVRMask(Quals);
-
- // Enforce C99 6.7.3p2: "Types other than pointer types derived from
- // object or incomplete types shall not be restrict-qualified."
- if (Qs.hasRestrict() && !T->isIncompleteOrObjectType()) {
- Diag(Loc, diag::err_typecheck_invalid_restrict_invalid_pointee)
- << T;
- Qs.removeRestrict();
- }
-
assert(!T->isObjCObjectType() && "Should build ObjCObjectPointerType");
// Build the pointer type.
- return Context.getQualifiedType(Context.getPointerType(T), Qs);
+ return Context.getPointerType(T);
}
/// \brief Build a reference type.
///
/// \param T The type to which we'll be building a reference.
///
-/// \param CVR The cvr-qualifiers to be applied to the reference type.
-///
/// \param Loc The location of the entity whose type involves this
/// reference type or, if there is no such entity, the location of the
/// type that will have reference type.
@@ -528,10 +557,8 @@ 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 SpelledAsLValue,
- unsigned CVR, SourceLocation Loc,
+ SourceLocation Loc,
DeclarationName Entity) {
- Qualifiers Quals = Qualifiers::fromCVRMask(CVR);
-
bool LValueRef = SpelledAsLValue || T->getAs<LValueReferenceType>();
// C++0x [dcl.typedef]p9: If a typedef TD names a type that is a
@@ -562,31 +589,10 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue,
return QualType();
}
- // Enforce C99 6.7.3p2: "Types other than pointer types derived from
- // object or incomplete types shall not be restrict-qualified."
- if (Quals.hasRestrict() && !T->isIncompleteOrObjectType()) {
- Diag(Loc, diag::err_typecheck_invalid_restrict_invalid_pointee)
- << T;
- Quals.removeRestrict();
- }
-
- // C++ [dcl.ref]p1:
- // [...] Cv-qualified references are ill-formed except when the
- // cv-qualifiers are introduced through the use of a typedef
- // (7.1.3) or of a template type argument (14.3), in which case
- // the cv-qualifiers are ignored.
- //
- // We diagnose extraneous cv-qualifiers for the non-typedef,
- // non-template type argument case within the parser. Here, we just
- // ignore any extraneous cv-qualifiers.
- Quals.removeConst();
- Quals.removeVolatile();
-
// Handle restrict on references.
if (LValueRef)
- return Context.getQualifiedType(
- Context.getLValueReferenceType(T, SpelledAsLValue), Quals);
- return Context.getQualifiedType(Context.getRValueReferenceType(T), Quals);
+ return Context.getLValueReferenceType(T, SpelledAsLValue);
+ return Context.getRValueReferenceType(T);
}
/// \brief Build an array type.
@@ -597,9 +603,6 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue,
///
/// \param ArraySize Expression describing the size of the array.
///
-/// \param Quals The cvr-qualifiers to be applied to the array's
-/// element type.
-///
/// \param Loc The location of the entity whose type involves this
/// array type or, if there is no such entity, the location of the
/// type that will have array type.
@@ -815,7 +818,7 @@ QualType Sema::BuildFunctionType(QualType T,
<< T->isFunctionType() << T;
return QualType();
}
-
+
bool Invalid = false;
for (unsigned Idx = 0; Idx < NumParamTypes; ++Idx) {
QualType ParamType = adjustParameterType(ParamTypes[Idx]);
@@ -846,10 +849,8 @@ QualType Sema::BuildFunctionType(QualType T,
/// \returns a member pointer type, if successful, or a NULL type if there was
/// an error.
QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
- unsigned CVR, SourceLocation Loc,
+ SourceLocation Loc,
DeclarationName Entity) {
- Qualifiers Quals = Qualifiers::fromCVRMask(CVR);
-
// Verify that we're not building a pointer to pointer to function with
// exception specification.
if (CheckDistantExceptionSpec(T)) {
@@ -863,7 +864,7 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
T = Context.getCanonicalType(T);
}
- // C++ 8.3.3p3: A pointer to member shall not pointer to ... a member
+ // C++ 8.3.3p3: A pointer to member shall not point to ... a member
// with reference type, or "cv void."
if (T->isReferenceType()) {
Diag(Loc, diag::err_illegal_decl_mempointer_to_reference)
@@ -877,24 +878,12 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
return QualType();
}
- // Enforce C99 6.7.3p2: "Types other than pointer types derived from
- // object or incomplete types shall not be restrict-qualified."
- if (Quals.hasRestrict() && !T->isIncompleteOrObjectType()) {
- Diag(Loc, diag::err_typecheck_invalid_restrict_invalid_pointee)
- << T;
-
- // FIXME: If we're doing this as part of template instantiation,
- // we should return immediately.
- Quals.removeRestrict();
- }
-
if (!Class->isDependentType() && !Class->isRecordType()) {
Diag(Loc, diag::err_mempointer_in_nonclass_type) << Class;
return QualType();
}
- return Context.getQualifiedType(
- Context.getMemberPointerType(T, Class.getTypePtr()), Quals);
+ return Context.getMemberPointerType(T, Class.getTypePtr());
}
/// \brief Build a block pointer type.
@@ -912,7 +901,7 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
///
/// \returns A suitable block pointer type, if there are no
/// errors. Otherwise, returns a NULL type.
-QualType Sema::BuildBlockPointerType(QualType T, unsigned CVR,
+QualType Sema::BuildBlockPointerType(QualType T,
SourceLocation Loc,
DeclarationName Entity) {
if (!T->isFunctionType()) {
@@ -920,8 +909,7 @@ QualType Sema::BuildBlockPointerType(QualType T, unsigned CVR,
return QualType();
}
- Qualifiers Quals = Qualifiers::fromCVRMask(CVR);
- return Context.getQualifiedType(Context.getBlockPointerType(T), Quals);
+ return Context.getBlockPointerType(T);
}
QualType Sema::GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo) {
@@ -947,9 +935,11 @@ QualType Sema::GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo) {
/// If OwnedDecl is non-NULL, and this declarator's decl-specifier-seq
/// owns the declaration of a type (e.g., the definition of a struct
/// type), then *OwnedDecl will receive the owned declaration.
-QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
- TypeSourceInfo **TInfo,
- TagDecl **OwnedDecl) {
+///
+/// The result of this call will never be null, but the associated
+/// type may be a null type if there's an unrecoverable error.
+TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
+ TagDecl **OwnedDecl) {
// Determine the type of the declarator. Not all forms of declarator
// have a type.
QualType T;
@@ -980,22 +970,18 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
// Constructors and destructors don't have return types. Use
// "void" instead.
T = Context.VoidTy;
-
- if (TInfo)
- ReturnTypeInfo = Context.getTrivialTypeSourceInfo(T,
- D.getName().StartLocation);
break;
case UnqualifiedId::IK_ConversionFunctionId:
// The result type of a conversion function is the type that it
// converts to.
T = GetTypeFromParser(D.getName().ConversionFunctionId,
- TInfo? &ReturnTypeInfo : 0);
+ &ReturnTypeInfo);
break;
}
if (T.isNull())
- return T;
+ return Context.getNullTypeSourceInfo();
if (T == Context.UndeducedAutoTy) {
int Error = -1;
@@ -1059,8 +1045,9 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
if (!LangOpts.Blocks)
Diag(DeclType.Loc, diag::err_blocks_disable);
- T = BuildBlockPointerType(T, DeclType.Cls.TypeQuals, D.getIdentifierLoc(),
- Name);
+ T = BuildBlockPointerType(T, D.getIdentifierLoc(), Name);
+ if (DeclType.Cls.TypeQuals)
+ T = BuildQualifiedType(T, DeclType.Loc, DeclType.Cls.TypeQuals);
break;
case DeclaratorChunk::Pointer:
// Verify that we're not building a pointer to pointer to function with
@@ -1072,15 +1059,15 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
}
if (getLangOptions().ObjC1 && T->getAs<ObjCObjectType>()) {
T = Context.getObjCObjectPointerType(T);
- T = Context.getCVRQualifiedType(T, DeclType.Ptr.TypeQuals);
+ if (DeclType.Ptr.TypeQuals)
+ T = BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals);
break;
}
- T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name);
+ T = BuildPointerType(T, DeclType.Loc, Name);
+ if (DeclType.Ptr.TypeQuals)
+ T = BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals);
break;
case DeclaratorChunk::Reference: {
- Qualifiers Quals;
- if (DeclType.Ref.HasRestrict) Quals.addRestrict();
-
// Verify that we're not building a reference to pointer to function with
// exception specification.
if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) {
@@ -1088,8 +1075,11 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
D.setInvalidType(true);
// Build the type anyway.
}
- T = BuildReferenceType(T, DeclType.Ref.LValueRef, Quals,
- DeclType.Loc, Name);
+ T = BuildReferenceType(T, DeclType.Ref.LValueRef, DeclType.Loc, Name);
+
+ Qualifiers Quals;
+ if (DeclType.Ref.HasRestrict)
+ T = BuildQualifiedType(T, DeclType.Loc, Qualifiers::Restrict);
break;
}
case DeclaratorChunk::Array: {
@@ -1139,6 +1129,48 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
D.setInvalidType(true);
}
+ // cv-qualifiers on return types are pointless except when the type is a
+ // class type in C++.
+ if (T.getCVRQualifiers() && D.getDeclSpec().getTypeQualifiers() &&
+ (!getLangOptions().CPlusPlus ||
+ (!T->isDependentType() && !T->isRecordType()))) {
+ unsigned Quals = D.getDeclSpec().getTypeQualifiers();
+ std::string QualStr;
+ unsigned NumQuals = 0;
+ SourceLocation Loc;
+ if (Quals & Qualifiers::Const) {
+ Loc = D.getDeclSpec().getConstSpecLoc();
+ ++NumQuals;
+ QualStr = "const";
+ }
+ if (Quals & Qualifiers::Volatile) {
+ if (NumQuals == 0) {
+ Loc = D.getDeclSpec().getVolatileSpecLoc();
+ QualStr = "volatile";
+ } else
+ QualStr += " volatile";
+ ++NumQuals;
+ }
+ if (Quals & Qualifiers::Restrict) {
+ if (NumQuals == 0) {
+ Loc = D.getDeclSpec().getRestrictSpecLoc();
+ QualStr = "restrict";
+ } else
+ QualStr += " restrict";
+ ++NumQuals;
+ }
+ assert(NumQuals > 0 && "No known qualifiers?");
+
+ SemaDiagnosticBuilder DB = Diag(Loc, diag::warn_qual_return_type);
+ DB << QualStr << NumQuals;
+ if (Quals & Qualifiers::Const)
+ DB << FixItHint::CreateRemoval(D.getDeclSpec().getConstSpecLoc());
+ if (Quals & Qualifiers::Volatile)
+ DB << FixItHint::CreateRemoval(D.getDeclSpec().getVolatileSpecLoc());
+ if (Quals & Qualifiers::Restrict)
+ DB << FixItHint::CreateRemoval(D.getDeclSpec().getRestrictSpecLoc());
+ }
+
if (getLangOptions().CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) {
// C++ [dcl.fct]p6:
// Types shall not be defined in return or parameter types.
@@ -1154,29 +1186,14 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
Diag(FTI.getThrowLoc(), diag::err_exception_spec_in_typedef);
- if (FTI.NumArgs == 0) {
- if (getLangOptions().CPlusPlus) {
- // C++ 8.3.5p2: If the parameter-declaration-clause is empty, the
- // function takes no arguments.
- llvm::SmallVector<QualType, 4> Exceptions;
- Exceptions.reserve(FTI.NumExceptions);
- for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
- // FIXME: Preserve type source info.
- QualType ET = GetTypeFromParser(FTI.Exceptions[ei].Ty);
- // Check that the type is valid for an exception spec, and drop it
- // if not.
- if (!CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range))
- Exceptions.push_back(ET);
- }
- T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, FTI.TypeQuals,
- FTI.hasExceptionSpec,
- FTI.hasAnyExceptionSpec,
- Exceptions.size(), Exceptions.data(),
- FunctionType::ExtInfo());
- } else if (FTI.isVariadic) {
- // We allow a zero-parameter variadic function in C if the
- // function is marked with the "overloadable"
- // attribute. Scan for this attribute now.
+ if (!FTI.NumArgs && !FTI.isVariadic && !getLangOptions().CPlusPlus) {
+ // Simple void foo(), where the incoming T is the result type.
+ T = Context.getFunctionNoProtoType(T);
+ } else {
+ // We allow a zero-parameter variadic function in C if the
+ // function is marked with the "overloadable" attribute. Scan
+ // for this attribute now.
+ if (!FTI.NumArgs && FTI.isVariadic && !getLangOptions().CPlusPlus) {
bool Overloadable = false;
for (const AttributeList *Attrs = D.getAttributes();
Attrs; Attrs = Attrs->getNext()) {
@@ -1188,21 +1205,20 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
if (!Overloadable)
Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg);
- T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, 0,
- false, false, 0, 0,
- FunctionType::ExtInfo());
- } else {
- // Simple void foo(), where the incoming T is the result type.
- T = Context.getFunctionNoProtoType(T);
}
- } else if (FTI.ArgInfo[0].Param == 0) {
- // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
- Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
- D.setInvalidType(true);
- } else {
+
+ if (FTI.NumArgs && FTI.ArgInfo[0].Param == 0) {
+ // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function
+ // definition.
+ Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
+ D.setInvalidType(true);
+ break;
+ }
+
// Otherwise, we have a function with an argument list that is
// potentially variadic.
llvm::SmallVector<QualType, 16> ArgTys;
+ ArgTys.reserve(FTI.NumArgs);
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
ParmVarDecl *Param =
@@ -1278,13 +1294,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
break;
}
case DeclaratorChunk::MemberPointer:
- // Verify that we're not building a pointer to pointer to function with
- // exception specification.
- if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) {
- Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
- D.setInvalidType(true);
- // Build the type anyway.
- }
// The scope spec must refer to a class, or be dependent.
QualType ClsType;
if (DeclType.Mem.Scope().isInvalid()) {
@@ -1323,11 +1332,12 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
}
if (!ClsType.isNull())
- T = BuildMemberPointerType(T, ClsType, DeclType.Mem.TypeQuals,
- DeclType.Loc, D.getIdentifier());
+ T = BuildMemberPointerType(T, ClsType, DeclType.Loc, D.getIdentifier());
if (T.isNull()) {
T = Context.IntTy;
D.setInvalidType(true);
+ } else if (DeclType.Mem.TypeQuals) {
+ T = BuildQualifiedType(T, DeclType.Loc, DeclType.Mem.TypeQuals);
}
break;
}
@@ -1352,18 +1362,19 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
// for a nonstatic member function, the function type to which a pointer
// to member refers, or the top-level function type of a function typedef
// declaration.
+ bool FreeFunction = (D.getContext() != Declarator::MemberContext &&
+ (!D.getCXXScopeSpec().isSet() ||
+ !computeDeclContext(D.getCXXScopeSpec(), /*FIXME:*/true)->isRecord()));
if (FnTy->getTypeQuals() != 0 &&
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
- ((D.getContext() != Declarator::MemberContext &&
- (!D.getCXXScopeSpec().isSet() ||
- !computeDeclContext(D.getCXXScopeSpec(), /*FIXME:*/true)
- ->isRecord())) ||
+ (FreeFunction ||
D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)) {
if (D.isFunctionDeclarator())
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_function_type);
else
Diag(D.getIdentifierLoc(),
- diag::err_invalid_qualified_typedef_function_type_use);
+ diag::err_invalid_qualified_typedef_function_type_use)
+ << FreeFunction;
// Strip the cv-quals from the type.
T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(),
@@ -1372,6 +1383,11 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
}
}
+ // If there's a constexpr specifier, treat it as a top-level const.
+ if (D.getDeclSpec().isConstexprSpecified()) {
+ T.addConst();
+ }
+
// Process any function attributes we might have delayed from the
// declaration-specifiers.
ProcessDelayedFnAttrs(*this, T, FnAttrsFromDeclSpec);
@@ -1386,14 +1402,11 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
DiagnoseDelayedFnAttrs(*this, FnAttrsFromPreviousChunk);
- if (TInfo) {
- if (D.isInvalidType())
- *TInfo = 0;
- else
- *TInfo = GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo);
- }
-
- return T;
+ if (T.isNull())
+ return Context.getNullTypeSourceInfo();
+ else if (D.isInvalidType())
+ return Context.getTrivialTypeSourceInfo(T);
+ return GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo);
}
namespace {
@@ -1527,6 +1540,28 @@ namespace {
// FIXME: load appropriate source location.
TL.setNameLoc(DS.getTypeSpecTypeLoc());
}
+ void VisitDependentTemplateSpecializationTypeLoc(
+ DependentTemplateSpecializationTypeLoc TL) {
+ ElaboratedTypeKeyword Keyword
+ = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
+ if (Keyword == ETK_Typename) {
+ TypeSourceInfo *TInfo = 0;
+ Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+ if (TInfo) {
+ TL.copy(cast<DependentTemplateSpecializationTypeLoc>(
+ TInfo->getTypeLoc()));
+ return;
+ }
+ }
+ TL.initializeLocal(SourceLocation());
+ TL.setKeywordLoc(Keyword != ETK_None
+ ? DS.getTypeSpecTypeLoc()
+ : SourceLocation());
+ const CXXScopeSpec& SS = DS.getTypeSpecScope();
+ TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange());
+ // FIXME: load appropriate source location.
+ TL.setNameLoc(DS.getTypeSpecTypeLoc());
+ }
void VisitTypeLoc(TypeLoc TL) {
// FIXME: add other typespec types and change this to an assert.
@@ -1651,53 +1686,14 @@ void LocInfoType::getAsStringInternal(std::string &Str,
" GetTypeFromParser");
}
-/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types that
-/// may be similar (C++ 4.4), replaces T1 and T2 with the type that
-/// they point to and return true. If T1 and T2 aren't pointer types
-/// or pointer-to-member types, or if they are not similar at this
-/// level, returns false and leaves T1 and T2 unchanged. Top-level
-/// qualifiers on T1 and T2 are ignored. This function will typically
-/// be called in a loop that successively "unwraps" pointer and
-/// pointer-to-member types to compare them at each level.
-bool Sema::UnwrapSimilarPointerTypes(QualType& T1, QualType& T2) {
- const PointerType *T1PtrType = T1->getAs<PointerType>(),
- *T2PtrType = T2->getAs<PointerType>();
- if (T1PtrType && T2PtrType) {
- T1 = T1PtrType->getPointeeType();
- T2 = T2PtrType->getPointeeType();
- return true;
- }
-
- const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(),
- *T2MPType = T2->getAs<MemberPointerType>();
- if (T1MPType && T2MPType &&
- Context.getCanonicalType(T1MPType->getClass()) ==
- Context.getCanonicalType(T2MPType->getClass())) {
- T1 = T1MPType->getPointeeType();
- T2 = T2MPType->getPointeeType();
- return true;
- }
-
- if (getLangOptions().ObjC1) {
- const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(),
- *T2OPType = T2->getAs<ObjCObjectPointerType>();
- if (T1OPType && T2OPType) {
- T1 = T1OPType->getPointeeType();
- T2 = T2OPType->getPointeeType();
- return true;
- }
- }
- return false;
-}
-
Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
// C99 6.7.6: Type names have no identifier. This is already validated by
// the parser.
assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
- TypeSourceInfo *TInfo = 0;
TagDecl *OwnedTag = 0;
- QualType T = GetTypeForDeclarator(D, S, &TInfo, &OwnedTag);
+ TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S, &OwnedTag);
+ QualType T = TInfo->getType();
if (D.isInvalidType())
return true;
@@ -1714,9 +1710,7 @@ Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
<< Context.getTypeDeclType(OwnedTag);
}
- if (TInfo)
- T = CreateLocInfoType(T, TInfo);
-
+ T = CreateLocInfoType(T, TInfo);
return T.getAsOpaquePtr();
}
@@ -1934,7 +1928,8 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
/// The raw attribute should contain precisely 1 argument, the vector size for
/// the variable, measured in bytes. If curType and rawAttr are well formed,
/// this routine will return a new vector type.
-static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, Sema &S) {
+static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr,
+ Sema &S) {
// Check the attribute arugments.
if (Attr.getNumArgs() != 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
@@ -1977,7 +1972,8 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, S
// Success! Instantiate the vector type, the number of elements is > 0, and
// not required to be a power of 2, unlike GCC.
- CurType = S.Context.getVectorType(CurType, vectorSize/typeSize, false, false);
+ CurType = S.Context.getVectorType(CurType, vectorSize/typeSize,
+ VectorType::NotAltiVec);
}
void ProcessTypeAttributeList(Sema &S, QualType &Result,