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 845f4a5..f34362d 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -365,6 +365,9 @@
/// 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 18259ce..7dbbb7b 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -500,9 +500,9 @@
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 @@
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 3bb205a..e8d2c1e 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -134,7 +134,7 @@
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 5dc2713..79b800b 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -262,9 +262,9 @@
/// \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 @@
/// \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 @@
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.