diff options
-rw-r--r-- | include/clang/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 28 |
4 files changed, 25 insertions, 18 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 845f4a5efe..f34362d633 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -365,6 +365,9 @@ public: /// standard library. LazyDeclPtr StdBadAlloc; + /// \brief The C++ "type_info" declaration, which is defined in <typeinfo>. + RecordDecl *CXXTypeInfoDecl; + /// \brief The MSVC "_GUID" struct, which is defined in MSVC header files. RecordDecl *MSVCGuidDecl; diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 18259ceb78..7dbbb7b10a 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -500,9 +500,9 @@ ExprResult Parser::ParseCXXTypeid() { TypeResult Ty = ParseTypeName(); // Match the ')'. - MatchRHSPunctuation(tok::r_paren, LParenLoc); + RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); - if (Ty.isInvalid()) + if (Ty.isInvalid() || RParenLoc.isInvalid()) return ExprError(); Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, @@ -524,8 +524,10 @@ ExprResult Parser::ParseCXXTypeid() { if (Result.isInvalid()) SkipUntil(tok::r_paren); else { - MatchRHSPunctuation(tok::r_paren, LParenLoc); - + RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); + if (RParenLoc.isInvalid()) + return ExprError(); + Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, Result.release(), RParenLoc); } diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 3bb205ac17..e8d2c1e420 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -134,7 +134,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), PackContext(0), VisContext(0), ParsingDeclDepth(0), - IdResolver(pp.getLangOptions()), MSVCGuidDecl(0), + IdResolver(pp.getLangOptions()), CXXTypeInfoDecl(0), MSVCGuidDecl(0), GlobalNewDeleteDeclared(false), CompleteTranslationUnit(CompleteTranslationUnit), NumSFINAEErrors(0), SuppressAccessChecking(false), diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 5dc2713d64..79b800bc0f 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -262,9 +262,9 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, /// \brief Build a C++ typeid expression with a type operand. ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, - SourceLocation TypeidLoc, - TypeSourceInfo *Operand, - SourceLocation RParenLoc) { + SourceLocation TypeidLoc, + TypeSourceInfo *Operand, + SourceLocation RParenLoc) { // C++ [expr.typeid]p4: // The top-level cv-qualifiers of the lvalue expression or the type-id // that is the operand of typeid are always ignored. @@ -285,9 +285,9 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, /// \brief Build a C++ typeid expression with an expression operand. ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, - SourceLocation TypeidLoc, - Expr *E, - SourceLocation RParenLoc) { + SourceLocation TypeidLoc, + Expr *E, + SourceLocation RParenLoc) { bool isUnevaluatedOperand = true; if (E && !E->isTypeDependent()) { QualType T = E->getType(); @@ -343,14 +343,16 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, if (!StdNamespace) return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); - IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info"); - LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName); - LookupQualifiedName(R, getStdNamespace()); - RecordDecl *TypeInfoRecordDecl = R.getAsSingle<RecordDecl>(); - if (!TypeInfoRecordDecl) - return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); + if (!CXXTypeInfoDecl) { + IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info"); + LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName); + LookupQualifiedName(R, getStdNamespace()); + CXXTypeInfoDecl = R.getAsSingle<RecordDecl>(); + if (!CXXTypeInfoDecl) + return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); + } - QualType TypeInfoType = Context.getTypeDeclType(TypeInfoRecordDecl); + QualType TypeInfoType = Context.getTypeDeclType(CXXTypeInfoDecl); if (isType) { // The operand is a type; handle it as such. |