forked from OSchip/llvm-project
More __uuidof validation:
1. Do not validate for uuid attribute if the type is template dependent. 2. Search every class declaration and definition for the uuid attribute. llvm-svn: 122578
This commit is contained in:
parent
2ac8355ecd
commit
b7577657cd
|
@ -372,16 +372,23 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
|
||||||
return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
|
return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the CXXRecordDecl associated with QT bypassing 1 level of pointer,
|
/// Retrieve the UuidAttr associated with QT.
|
||||||
// reference or array type.
|
static UuidAttr *GetUuidAttrOfType(QualType QT) {
|
||||||
static CXXRecordDecl *GetCXXRecordOfUuidArg(QualType QT) {
|
// Optionally remove one level of pointer, reference or array indirection.
|
||||||
Type* Ty = QT.getTypePtr();;
|
Type *Ty = QT.getTypePtr();;
|
||||||
if (QT->isPointerType() || QT->isReferenceType())
|
if (QT->isPointerType() || QT->isReferenceType())
|
||||||
Ty = QT->getPointeeType().getTypePtr();
|
Ty = QT->getPointeeType().getTypePtr();
|
||||||
else if (QT->isArrayType())
|
else if (QT->isArrayType())
|
||||||
Ty = cast<ArrayType>(QT)->getElementType().getTypePtr();
|
Ty = cast<ArrayType>(QT)->getElementType().getTypePtr();
|
||||||
|
|
||||||
return Ty->getAsCXXRecordDecl();
|
// Loop all class definition and declaration looking for an uuid attribute.
|
||||||
|
CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
|
||||||
|
while (RD) {
|
||||||
|
if (UuidAttr *Uuid = RD->getAttr<UuidAttr>())
|
||||||
|
return Uuid;
|
||||||
|
RD = RD->getPreviousDeclaration();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Build a Microsoft __uuidof expression with a type operand.
|
/// \brief Build a Microsoft __uuidof expression with a type operand.
|
||||||
|
@ -389,11 +396,11 @@ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
|
||||||
SourceLocation TypeidLoc,
|
SourceLocation TypeidLoc,
|
||||||
TypeSourceInfo *Operand,
|
TypeSourceInfo *Operand,
|
||||||
SourceLocation RParenLoc) {
|
SourceLocation RParenLoc) {
|
||||||
// Make sure Operand has an associated GUID.
|
if (!Operand->getType()->isDependentType()) {
|
||||||
CXXRecordDecl* RD = GetCXXRecordOfUuidArg(Operand->getType());
|
if (!GetUuidAttrOfType(Operand->getType()))
|
||||||
if (!RD || !RD->getAttr<UuidAttr>())
|
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
|
||||||
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
|
}
|
||||||
|
|
||||||
// FIXME: add __uuidof semantic analysis for type operand.
|
// FIXME: add __uuidof semantic analysis for type operand.
|
||||||
return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
|
return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
|
||||||
Operand,
|
Operand,
|
||||||
|
@ -405,14 +412,12 @@ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
|
||||||
SourceLocation TypeidLoc,
|
SourceLocation TypeidLoc,
|
||||||
Expr *E,
|
Expr *E,
|
||||||
SourceLocation RParenLoc) {
|
SourceLocation RParenLoc) {
|
||||||
// Make sure E has an associated GUID.
|
if (!E->getType()->isDependentType()) {
|
||||||
// 0 is fine also.
|
if (!GetUuidAttrOfType(E->getType()) &&
|
||||||
CXXRecordDecl* RD = GetCXXRecordOfUuidArg(E->getType());
|
!E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
|
||||||
if ((!RD || !RD->getAttr<UuidAttr>()) &&
|
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
|
||||||
!E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
|
}
|
||||||
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
|
// FIXME: add __uuidof semantic analysis for type operand.
|
||||||
|
|
||||||
// FIXME: add __uuidof semantic analysis for expr operand.
|
|
||||||
return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
|
return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
|
||||||
E,
|
E,
|
||||||
SourceRange(TypeidLoc, RParenLoc)));
|
SourceRange(TypeidLoc, RParenLoc)));
|
||||||
|
|
|
@ -48,6 +48,11 @@ struct __declspec(uuid("000000A0-0000-0000-C000-000000000046"))
|
||||||
struct_with_uuid { };
|
struct_with_uuid { };
|
||||||
struct struct_without_uuid { };
|
struct struct_without_uuid { };
|
||||||
|
|
||||||
|
struct __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
|
||||||
|
struct_with_uuid2;
|
||||||
|
|
||||||
|
struct
|
||||||
|
struct_with_uuid2 {} ;
|
||||||
|
|
||||||
int uuid_sema_test()
|
int uuid_sema_test()
|
||||||
{
|
{
|
||||||
|
@ -55,6 +60,7 @@ int uuid_sema_test()
|
||||||
struct_without_uuid var_without_uuid[1];
|
struct_without_uuid var_without_uuid[1];
|
||||||
|
|
||||||
__uuidof(struct_with_uuid);
|
__uuidof(struct_with_uuid);
|
||||||
|
__uuidof(struct_with_uuid2);
|
||||||
__uuidof(struct_without_uuid); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
|
__uuidof(struct_without_uuid); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
|
||||||
__uuidof(struct_with_uuid*);
|
__uuidof(struct_with_uuid*);
|
||||||
__uuidof(struct_without_uuid*); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
|
__uuidof(struct_without_uuid*); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
|
||||||
|
@ -69,3 +75,13 @@ int uuid_sema_test()
|
||||||
__uuidof(0);
|
__uuidof(0);
|
||||||
__uuidof(1);// expected-error {{cannot call operator __uuidof on a type with no GUID}}
|
__uuidof(1);// expected-error {{cannot call operator __uuidof on a type with no GUID}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void template_uuid()
|
||||||
|
{
|
||||||
|
T expr;
|
||||||
|
|
||||||
|
__uuidof(T);
|
||||||
|
__uuidof(expr);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue