From: Douglas Gregor Date: Wed, 8 Sep 2010 23:14:30 +0000 (+0000) Subject: Fix a few minor issues with parsing and semantic analysis of C++ X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4eb4f0f96289cbece50c1270e02af3caf8779705;p=clang Fix a few minor issues with parsing and semantic analysis of C++ typeid expressions: - make sure we have a proper source location for the closing ')' - cache the declaration of std::type_info once we've found it git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113441 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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 . + 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(); - 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(); + 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.