Fix a few minor issues with parsing and semantic analysis of C++
authorDouglas Gregor <dgregor@apple.com>
Wed, 8 Sep 2010 23:14:30 +0000 (23:14 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 8 Sep 2010 23:14:30 +0000 (23:14 +0000)
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

include/clang/Sema/Sema.h
lib/Parse/ParseExprCXX.cpp
lib/Sema/Sema.cpp
lib/Sema/SemaExprCXX.cpp

index 845f4a5efe8c7d85ec75ae3ffb1922a0dbf16bbf..f34362d633f0bfbfa5ebf9de5eb88b9afca6ae74 100644 (file)
@@ -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;
 
index 18259ceb786c0ad121e08fca1ec3009a617c39e4..7dbbb7b10a4c054299710602620ef0087013f4bb 100644 (file)
@@ -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);
     }
index 3bb205ac17fb8ba2ec55078adebfbb06ac47b565..e8d2c1e4201ea5d2d6f1c2089d3006e2f919be80 100644 (file)
@@ -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),
index 5dc2713d64d8dd9293b189981ff041c51d2df690..79b800bc0fe2726b9a6a1bb0b05f4afc5bfe1999 100644 (file)
@@ -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.