зеркало из https://github.com/microsoft/clang-1.git
Microsoft's __uuidof operator implementation part 1.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113356 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
538e0d0292
Коммит
01b7c3028d
|
@ -396,6 +396,74 @@ public:
|
|||
virtual child_iterator child_end();
|
||||
};
|
||||
|
||||
/// CXXUuidofExpr - A microsoft C++ @c __uuidof expression, which gets
|
||||
/// the _GUID that corresponds to the supplied type or expression.
|
||||
///
|
||||
/// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr)
|
||||
class CXXUuidofExpr : public Expr {
|
||||
private:
|
||||
llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
|
||||
SourceRange Range;
|
||||
|
||||
public:
|
||||
CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
|
||||
: Expr(CXXUuidofExprClass, Ty,
|
||||
false, Operand->getType()->isDependentType()),
|
||||
Operand(Operand), Range(R) { }
|
||||
|
||||
CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R)
|
||||
: Expr(CXXUuidofExprClass, Ty,
|
||||
false, Operand->isTypeDependent()),
|
||||
Operand(Operand), Range(R) { }
|
||||
|
||||
CXXUuidofExpr(EmptyShell Empty, bool isExpr)
|
||||
: Expr(CXXUuidofExprClass, Empty) {
|
||||
if (isExpr)
|
||||
Operand = (Expr*)0;
|
||||
else
|
||||
Operand = (TypeSourceInfo*)0;
|
||||
}
|
||||
|
||||
bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
|
||||
|
||||
/// \brief Retrieves the type operand of this __uuidof() expression after
|
||||
/// various required adjustments (removing reference types, cv-qualifiers).
|
||||
QualType getTypeOperand() const;
|
||||
|
||||
/// \brief Retrieve source information for the type operand.
|
||||
TypeSourceInfo *getTypeOperandSourceInfo() const {
|
||||
assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
|
||||
return Operand.get<TypeSourceInfo *>();
|
||||
}
|
||||
|
||||
void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
|
||||
assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
|
||||
Operand = TSI;
|
||||
}
|
||||
|
||||
Expr *getExprOperand() const {
|
||||
assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
|
||||
return static_cast<Expr*>(Operand.get<Stmt *>());
|
||||
}
|
||||
|
||||
void setExprOperand(Expr *E) {
|
||||
assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
|
||||
Operand = E;
|
||||
}
|
||||
|
||||
virtual SourceRange getSourceRange() const { return Range; }
|
||||
void setSourceRange(SourceRange R) { Range = R; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXUuidofExprClass;
|
||||
}
|
||||
static bool classof(const CXXUuidofExpr *) { return true; }
|
||||
|
||||
// Iterators
|
||||
virtual child_iterator child_begin();
|
||||
virtual child_iterator child_end();
|
||||
};
|
||||
|
||||
/// CXXThisExpr - Represents the "this" expression in C++, which is a
|
||||
/// pointer to the object on which the current member function is
|
||||
/// executing (C++ [expr.prim]p3). Example:
|
||||
|
|
|
@ -1769,6 +1769,13 @@ DEF_TRAVERSE_STMT(CXXTypeidExpr, {
|
|||
TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_STMT(CXXUuidofExpr, {
|
||||
// The child-iterator will pick up the arg if it's an expression,
|
||||
// but not if it's a type.
|
||||
if (S->isTypeOperand())
|
||||
TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_STMT(TypesCompatibleExpr, {
|
||||
TRY_TO(TraverseTypeLoc(S->getArgTInfo1()->getTypeLoc()));
|
||||
TRY_TO(TraverseTypeLoc(S->getArgTInfo2()->getTypeLoc()));
|
||||
|
|
|
@ -2392,6 +2392,8 @@ def err_bad_dynamic_cast_not_polymorphic : Error<"%0 is not polymorphic">;
|
|||
// Other C++ expressions
|
||||
def err_need_header_before_typeid : Error<
|
||||
"you need to include <typeinfo> before using the 'typeid' operator">;
|
||||
def err_need_header_before_ms_uuidof : Error<
|
||||
"you need to include <guiddef.h> before using the '__uuidof' operator">;
|
||||
def err_incomplete_typeid : Error<"'typeid' of incomplete type %0">;
|
||||
def err_static_illegal_in_new : Error<
|
||||
"the 'static' modifier for the array size is not legal in new expressions">;
|
||||
|
|
|
@ -127,3 +127,7 @@ def ObjCIsaExpr : DStmt<Expr>;
|
|||
def ShuffleVectorExpr : DStmt<Expr>;
|
||||
def BlockExpr : DStmt<Expr>;
|
||||
def BlockDeclRefExpr : DStmt<Expr>;
|
||||
|
||||
// Microsoft Extensions.
|
||||
def CXXUuidofExpr : DStmt<Expr>;
|
||||
|
||||
|
|
|
@ -369,11 +369,13 @@ ALIAS("__volatile__" , volatile , KEYALL)
|
|||
// Microsoft extensions which should be disabled in strict conformance mode
|
||||
KEYWORD(__ptr64 , KEYMS)
|
||||
KEYWORD(__w64 , KEYMS)
|
||||
KEYWORD(__uuidof , KEYMS)
|
||||
ALIAS("_asm" , asm , KEYMS)
|
||||
ALIAS("_cdecl" , __cdecl , KEYMS)
|
||||
ALIAS("_fastcall" , __fastcall , KEYMS)
|
||||
ALIAS("_stdcall" , __stdcall , KEYMS)
|
||||
ALIAS("_thiscall" , __thiscall , KEYMS)
|
||||
ALIAS("_uuidof" ,__uuidof , KEYMS)
|
||||
|
||||
// Borland Extensions which should be disabled in strict conformance mode.
|
||||
ALIAS("_pascal" , __pascal , KEYBORLAND)
|
||||
|
|
|
@ -1028,6 +1028,10 @@ private:
|
|||
// C++ 5.2p1: C++ Type Identification
|
||||
ExprResult ParseCXXTypeid();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// C++ : Microsoft __uuidof Expression
|
||||
ExprResult ParseCXXUuidof();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// C++ 5.2.4: C++ Pseudo-Destructor Expressions
|
||||
ExprResult ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
|
||||
|
|
|
@ -365,6 +365,9 @@ public:
|
|||
/// standard library.
|
||||
LazyDeclPtr StdBadAlloc;
|
||||
|
||||
/// \brief The MSVC "_GUID" struct, which is defined in MSVC header files.
|
||||
RecordDecl *MSVCGuidDecl;
|
||||
|
||||
/// A flag to remember whether the implicit forms of operator new and delete
|
||||
/// have been declared.
|
||||
bool GlobalNewDeleteDeclared;
|
||||
|
@ -2156,6 +2159,22 @@ public:
|
|||
void *TyOrExpr,
|
||||
SourceLocation RParenLoc);
|
||||
|
||||
ExprResult BuildCXXUuidof(QualType TypeInfoType,
|
||||
SourceLocation TypeidLoc,
|
||||
TypeSourceInfo *Operand,
|
||||
SourceLocation RParenLoc);
|
||||
ExprResult BuildCXXUuidof(QualType TypeInfoType,
|
||||
SourceLocation TypeidLoc,
|
||||
Expr *Operand,
|
||||
SourceLocation RParenLoc);
|
||||
|
||||
/// ActOnCXXUuidof - Parse __uuidof( something ).
|
||||
virtual ExprResult ActOnCXXUuidof(SourceLocation OpLoc,
|
||||
SourceLocation LParenLoc, bool isType,
|
||||
void *TyOrExpr,
|
||||
SourceLocation RParenLoc);
|
||||
|
||||
|
||||
//// ActOnCXXThis - Parse 'this' pointer.
|
||||
ExprResult ActOnCXXThis(SourceLocation ThisLoc);
|
||||
|
||||
|
|
|
@ -875,6 +875,8 @@ namespace clang {
|
|||
EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr
|
||||
EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr).
|
||||
EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type).
|
||||
EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr).
|
||||
EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type).
|
||||
EXPR_CXX_THIS, // CXXThisExpr
|
||||
EXPR_CXX_THROW, // CXXThrowExpr
|
||||
EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr
|
||||
|
|
|
@ -39,6 +39,22 @@ Stmt::child_iterator CXXTypeidExpr::child_end() {
|
|||
: reinterpret_cast<Stmt **>(&Operand) + 1;
|
||||
}
|
||||
|
||||
QualType CXXUuidofExpr::getTypeOperand() const {
|
||||
assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
|
||||
return Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType()
|
||||
.getUnqualifiedType();
|
||||
}
|
||||
|
||||
// CXXUuidofExpr - has child iterators if the operand is an expression
|
||||
Stmt::child_iterator CXXUuidofExpr::child_begin() {
|
||||
return isTypeOperand() ? child_iterator()
|
||||
: reinterpret_cast<Stmt **>(&Operand);
|
||||
}
|
||||
Stmt::child_iterator CXXUuidofExpr::child_end() {
|
||||
return isTypeOperand() ? child_iterator()
|
||||
: reinterpret_cast<Stmt **>(&Operand) + 1;
|
||||
}
|
||||
|
||||
// CXXBoolLiteralExpr
|
||||
Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
|
||||
return child_iterator();
|
||||
|
|
|
@ -1002,6 +1002,16 @@ void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
|
|||
OS << ")";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
|
||||
OS << "__uuidof(";
|
||||
if (Node->isTypeOperand()) {
|
||||
OS << Node->getTypeOperand().getAsString(Policy);
|
||||
} else {
|
||||
PrintExpr(Node->getExprOperand());
|
||||
}
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
|
||||
OS << (Node->getValue() ? "true" : "false");
|
||||
}
|
||||
|
|
|
@ -687,6 +687,12 @@ void StmtProfiler::VisitCXXTypeidExpr(CXXTypeidExpr *S) {
|
|||
VisitType(S->getTypeOperand());
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitCXXUuidofExpr(CXXUuidofExpr *S) {
|
||||
VisitExpr(S);
|
||||
if (S->isTypeOperand())
|
||||
VisitType(S->getTypeOperand());
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitCXXThisExpr(CXXThisExpr *S) {
|
||||
VisitExpr(S);
|
||||
}
|
||||
|
|
|
@ -768,6 +768,9 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
|||
case tok::kw_typeid:
|
||||
Res = ParseCXXTypeid();
|
||||
break;
|
||||
case tok::kw___uuidof:
|
||||
Res = ParseCXXUuidof();
|
||||
break;
|
||||
case tok::kw_this:
|
||||
Res = ParseCXXThis();
|
||||
break;
|
||||
|
|
|
@ -534,6 +534,54 @@ ExprResult Parser::ParseCXXTypeid() {
|
|||
return move(Result);
|
||||
}
|
||||
|
||||
/// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression.
|
||||
///
|
||||
/// '__uuidof' '(' expression ')'
|
||||
/// '__uuidof' '(' type-id ')'
|
||||
///
|
||||
ExprResult Parser::ParseCXXUuidof() {
|
||||
assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!");
|
||||
|
||||
SourceLocation OpLoc = ConsumeToken();
|
||||
SourceLocation LParenLoc = Tok.getLocation();
|
||||
SourceLocation RParenLoc;
|
||||
|
||||
// __uuidof expressions are always parenthesized.
|
||||
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
|
||||
"__uuidof"))
|
||||
return ExprError();
|
||||
|
||||
ExprResult Result;
|
||||
|
||||
if (isTypeIdInParens()) {
|
||||
TypeResult Ty = ParseTypeName();
|
||||
|
||||
// Match the ')'.
|
||||
RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||
|
||||
if (Ty.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
Result = Actions.ActOnCXXUuidof(OpLoc, LParenLoc, /*isType=*/true,
|
||||
Ty.get().getAsOpaquePtr(), RParenLoc);
|
||||
} else {
|
||||
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
|
||||
Result = ParseExpression();
|
||||
|
||||
// Match the ')'.
|
||||
if (Result.isInvalid())
|
||||
SkipUntil(tok::r_paren);
|
||||
else {
|
||||
RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||
|
||||
Result = Actions.ActOnCXXUuidof(OpLoc, LParenLoc, /*isType=*/false,
|
||||
Result.release(), RParenLoc);
|
||||
}
|
||||
}
|
||||
|
||||
return move(Result);
|
||||
}
|
||||
|
||||
/// \brief Parse a C++ pseudo-destructor expression after the base,
|
||||
/// . or -> operator, and nested-name-specifier have already been
|
||||
/// parsed.
|
||||
|
|
|
@ -138,7 +138,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
|
|||
CompleteTranslationUnit(CompleteTranslationUnit),
|
||||
NumSFINAEErrors(0), SuppressAccessChecking(false),
|
||||
NonInstantiationEntries(0), CurrentInstantiationScope(0), TyposCorrected(0),
|
||||
AnalysisWarnings(*this)
|
||||
AnalysisWarnings(*this), MSVCGuidDecl(0)
|
||||
{
|
||||
TUScope = 0;
|
||||
if (getLangOptions().CPlusPlus)
|
||||
|
|
|
@ -370,6 +370,62 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
|
|||
return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a Microsoft __uuidof expression with a type operand.
|
||||
ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
|
||||
SourceLocation TypeidLoc,
|
||||
TypeSourceInfo *Operand,
|
||||
SourceLocation RParenLoc) {
|
||||
// FIXME: add __uuidof semantic analysis for type operand.
|
||||
return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
|
||||
Operand,
|
||||
SourceRange(TypeidLoc, RParenLoc)));
|
||||
}
|
||||
|
||||
/// \brief Build a Microsoft __uuidof expression with an expression operand.
|
||||
ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
|
||||
SourceLocation TypeidLoc,
|
||||
Expr *E,
|
||||
SourceLocation RParenLoc) {
|
||||
// FIXME: add __uuidof semantic analysis for expr operand.
|
||||
return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
|
||||
E,
|
||||
SourceRange(TypeidLoc, RParenLoc)));
|
||||
}
|
||||
|
||||
/// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression);
|
||||
ExprResult
|
||||
Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc,
|
||||
bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
|
||||
// If MSVCGuidDecl has not been cached, do the lookup.
|
||||
if (!MSVCGuidDecl) {
|
||||
IdentifierInfo *GuidII = &PP.getIdentifierTable().get("_GUID");
|
||||
LookupResult R(*this, GuidII, SourceLocation(), LookupTagName);
|
||||
LookupQualifiedName(R, Context.getTranslationUnitDecl());
|
||||
MSVCGuidDecl = R.getAsSingle<RecordDecl>();
|
||||
if (!MSVCGuidDecl)
|
||||
return ExprError(Diag(OpLoc, diag::err_need_header_before_ms_uuidof));
|
||||
}
|
||||
|
||||
QualType GuidType = Context.getTypeDeclType(MSVCGuidDecl);
|
||||
|
||||
if (isType) {
|
||||
// The operand is a type; handle it as such.
|
||||
TypeSourceInfo *TInfo = 0;
|
||||
QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
|
||||
&TInfo);
|
||||
if (T.isNull())
|
||||
return ExprError();
|
||||
|
||||
if (!TInfo)
|
||||
TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
|
||||
|
||||
return BuildCXXUuidof(GuidType, OpLoc, TInfo, RParenLoc);
|
||||
}
|
||||
|
||||
// The operand is an expression.
|
||||
return BuildCXXUuidof(GuidType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
|
||||
}
|
||||
|
||||
/// ActOnCXXBoolLiteral - Parse {true,false} literals.
|
||||
ExprResult
|
||||
Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
|
||||
|
|
|
@ -1513,6 +1513,7 @@ public:
|
|||
RParenLoc);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Build a new C++ typeid(expr) expression.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new expression.
|
||||
|
@ -1525,6 +1526,30 @@ public:
|
|||
RParenLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new C++ __uuidof(type) expression.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new expression.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType,
|
||||
SourceLocation TypeidLoc,
|
||||
TypeSourceInfo *Operand,
|
||||
SourceLocation RParenLoc) {
|
||||
return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand,
|
||||
RParenLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new C++ __uuidof(expr) expression.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new expression.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType,
|
||||
SourceLocation TypeidLoc,
|
||||
Expr *Operand,
|
||||
SourceLocation RParenLoc) {
|
||||
return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand,
|
||||
RParenLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new C++ "this" expression.
|
||||
///
|
||||
/// By default, builds a new "this" expression without performing any
|
||||
|
@ -5143,6 +5168,44 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
|
|||
E->getLocEnd());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
ExprResult
|
||||
TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
|
||||
if (E->isTypeOperand()) {
|
||||
TypeSourceInfo *TInfo
|
||||
= getDerived().TransformType(E->getTypeOperandSourceInfo());
|
||||
if (!TInfo)
|
||||
return ExprError();
|
||||
|
||||
if (!getDerived().AlwaysRebuild() &&
|
||||
TInfo == E->getTypeOperandSourceInfo())
|
||||
return SemaRef.Owned(E->Retain());
|
||||
|
||||
return getDerived().RebuildCXXTypeidExpr(E->getType(),
|
||||
E->getLocStart(),
|
||||
TInfo,
|
||||
E->getLocEnd());
|
||||
}
|
||||
|
||||
// We don't know whether the expression is potentially evaluated until
|
||||
// after we perform semantic analysis, so the expression is potentially
|
||||
// potentially evaluated.
|
||||
EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
|
||||
|
||||
ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
|
||||
if (SubExpr.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
if (!getDerived().AlwaysRebuild() &&
|
||||
SubExpr.get() == E->getExprOperand())
|
||||
return SemaRef.Owned(E->Retain());
|
||||
|
||||
return getDerived().RebuildCXXUuidofExpr(E->getType(),
|
||||
E->getLocStart(),
|
||||
SubExpr.get(),
|
||||
E->getLocEnd());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
ExprResult
|
||||
TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
|
||||
|
|
|
@ -134,6 +134,7 @@ namespace clang {
|
|||
void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
|
||||
void VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
|
||||
void VisitCXXTypeidExpr(CXXTypeidExpr *E);
|
||||
void VisitCXXUuidofExpr(CXXUuidofExpr *E);
|
||||
void VisitCXXThisExpr(CXXThisExpr *E);
|
||||
void VisitCXXThrowExpr(CXXThrowExpr *E);
|
||||
void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
|
||||
|
@ -1028,6 +1029,18 @@ void ASTStmtReader::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
|
|||
// typeid(42+2)
|
||||
E->setExprOperand(Reader.ReadSubExpr());
|
||||
}
|
||||
void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
|
||||
VisitExpr(E);
|
||||
E->setSourceRange(Reader.ReadSourceRange(Record, Idx));
|
||||
if (E->isTypeOperand()) { // __uuidof(ComType)
|
||||
E->setTypeOperandSourceInfo(
|
||||
Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
|
||||
return;
|
||||
}
|
||||
|
||||
// __uuidof(expr)
|
||||
E->setExprOperand(Reader.ReadSubExpr());
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) {
|
||||
VisitExpr(E);
|
||||
|
@ -1678,6 +1691,12 @@ Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) {
|
|||
case EXPR_CXX_TYPEID_TYPE:
|
||||
S = new (Context) CXXTypeidExpr(Empty, false);
|
||||
break;
|
||||
case EXPR_CXX_UUIDOF_EXPR:
|
||||
S = new (Context) CXXUuidofExpr(Empty, true);
|
||||
break;
|
||||
case EXPR_CXX_UUIDOF_TYPE:
|
||||
S = new (Context) CXXUuidofExpr(Empty, false);
|
||||
break;
|
||||
case EXPR_CXX_THIS:
|
||||
S = new (Context) CXXThisExpr(Empty);
|
||||
break;
|
||||
|
|
|
@ -131,6 +131,7 @@ namespace clang {
|
|||
void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
|
||||
void VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
|
||||
void VisitCXXTypeidExpr(CXXTypeidExpr *E);
|
||||
void VisitCXXUuidofExpr(CXXUuidofExpr *E);
|
||||
void VisitCXXThisExpr(CXXThisExpr *E);
|
||||
void VisitCXXThrowExpr(CXXThrowExpr *E);
|
||||
void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
|
||||
|
@ -1039,6 +1040,18 @@ void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
|
|||
}
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
|
||||
VisitExpr(E);
|
||||
Writer.AddSourceRange(E->getSourceRange(), Record);
|
||||
if (E->isTypeOperand()) {
|
||||
Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
|
||||
Code = serialization::EXPR_CXX_UUIDOF_TYPE;
|
||||
} else {
|
||||
Writer.AddStmt(E->getExprOperand());
|
||||
Code = serialization::EXPR_CXX_UUIDOF_EXPR;
|
||||
}
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
|
||||
VisitExpr(E);
|
||||
Writer.AddSourceLocation(E->getLocation(), Record);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions -Wno-missing-declarations -x objective-c++ %s
|
||||
// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions -Wno-unused-value -Wno-missing-declarations -x objective-c++ %s
|
||||
__stdcall int func0();
|
||||
int __stdcall func();
|
||||
typedef int (__cdecl *tptr)();
|
||||
|
@ -36,3 +36,40 @@ typedef bool (__stdcall __stdcall *blarg)(int);
|
|||
char x = FOO(a);
|
||||
|
||||
typedef enum E { e1 };
|
||||
|
||||
|
||||
void uuidof_test1()
|
||||
{
|
||||
__uuidof(0); // expected-error {{you need to include <guiddef.h> before using the '__uuidof' operator}}
|
||||
}
|
||||
|
||||
typedef struct _GUID
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[8];
|
||||
} GUID;
|
||||
struct __declspec(uuid("00000000-0000-0000-3231-000000000046")) A { };
|
||||
struct __declspec(uuid("00000000-0000-0000-1234-000000000047")) B { };
|
||||
class C {};
|
||||
|
||||
void uuidof_test2()
|
||||
{
|
||||
A* a = new A;
|
||||
B b;
|
||||
__uuidof(A);
|
||||
__uuidof(*a);
|
||||
__uuidof(B);
|
||||
__uuidof(&b);
|
||||
_uuidof(0);
|
||||
|
||||
// FIXME, this must not compile
|
||||
_uuidof(1);
|
||||
// FIXME, this must not compile
|
||||
_uuidof(C);
|
||||
|
||||
C c;
|
||||
// FIXME, this must not compile
|
||||
_uuidof(c);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче