[cfe-commits] r113492 - in /cfe/trunk: include/clang/AST/ExprCXX.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/ExprCXX.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp test/Index/load-stmts.cpp tools/libclang/CIndex.cpp

Douglas Gregor dgregor at apple.com
Thu Sep 9 09:14:45 PDT 2010


Author: dgregor
Date: Thu Sep  9 11:14:44 2010
New Revision: 113492

URL: http://llvm.org/viewvc/llvm-project?rev=113492&view=rev
Log:
Add proper type-source information to UnaryTypeTraitExpr, including
libclang visitation.

Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
    cfe/trunk/test/Index/load-stmts.cpp
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Thu Sep  9 11:14:44 2010
@@ -1378,24 +1378,28 @@
   /// RParen - The location of the closing paren.
   SourceLocation RParen;
 
-  /// QueriedType - The type we're testing.
-  QualType QueriedType;
+  TypeSourceInfo *QueriedType;
 
 public:
-  UnaryTypeTraitExpr(SourceLocation loc, UnaryTypeTrait utt, QualType queried,
+  UnaryTypeTraitExpr(SourceLocation loc, UnaryTypeTrait utt, 
+                     TypeSourceInfo *queried,
                      SourceLocation rparen, QualType ty)
-    : Expr(UnaryTypeTraitExprClass, ty, false, queried->isDependentType()),
+    : Expr(UnaryTypeTraitExprClass, ty, false, 
+           queried->getType()->isDependentType()),
       UTT(utt), Loc(loc), RParen(rparen), QueriedType(queried) { }
 
   explicit UnaryTypeTraitExpr(EmptyShell Empty)
-    : Expr(UnaryTypeTraitExprClass, Empty), UTT((UnaryTypeTrait)0) { }
+    : Expr(UnaryTypeTraitExprClass, Empty), UTT((UnaryTypeTrait)0), 
+      QueriedType() { }
 
   virtual SourceRange getSourceRange() const { return SourceRange(Loc, RParen);}
 
   UnaryTypeTrait getTrait() const { return UTT; }
 
-  QualType getQueriedType() const { return QueriedType; }
+  QualType getQueriedType() const { return QueriedType->getType(); }
 
+  TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
+  
   bool EvaluateTrait(ASTContext&) const;
 
   static bool classof(const Stmt *T) {

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Thu Sep  9 11:14:44 2010
@@ -1782,7 +1782,7 @@
   })
 
 DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, {
-    TRY_TO(TraverseType(S->getQueriedType()));
+    TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
   })
 
 // These exprs (most of them), do not need any action except iterating

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Sep  9 11:14:44 2010
@@ -2260,10 +2260,14 @@
   /// pseudo-functions.
   ExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
                                  SourceLocation KWLoc,
-                                 SourceLocation LParen,
                                  ParsedType Ty,
                                  SourceLocation RParen);
 
+  ExprResult BuildUnaryTypeTrait(UnaryTypeTrait OTT,
+                                 SourceLocation KWLoc,
+                                 TypeSourceInfo *T,
+                                 SourceLocation RParen);
+
   ExprResult ActOnStartCXXMemberReference(Scope *S,
                                           Expr *Base,
                                           SourceLocation OpLoc,

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Thu Sep  9 11:14:44 2010
@@ -328,30 +328,31 @@
 }
 
 bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
+  QualType T = getQueriedType();
   switch(UTT) {
   default: assert(false && "Unknown type trait or not implemented");
-  case UTT_IsPOD: return QueriedType->isPODType();
-  case UTT_IsLiteral: return QueriedType->isLiteralType();
+  case UTT_IsPOD: return T->isPODType();
+  case UTT_IsLiteral: return T->isLiteralType();
   case UTT_IsClass: // Fallthrough
   case UTT_IsUnion:
-    if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
+    if (const RecordType *Record = T->getAs<RecordType>()) {
       bool Union = Record->getDecl()->isUnion();
       return UTT == UTT_IsUnion ? Union : !Union;
     }
     return false;
-  case UTT_IsEnum: return QueriedType->isEnumeralType();
+  case UTT_IsEnum: return T->isEnumeralType();
   case UTT_IsPolymorphic:
-    if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
+    if (const RecordType *Record = T->getAs<RecordType>()) {
       // Type traits are only parsed in C++, so we've got CXXRecords.
       return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
     }
     return false;
   case UTT_IsAbstract:
-    if (const RecordType *RT = QueriedType->getAs<RecordType>())
+    if (const RecordType *RT = T->getAs<RecordType>())
       return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
     return false;
   case UTT_IsEmpty:
-    if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
+    if (const RecordType *Record = T->getAs<RecordType>()) {
       return !Record->getDecl()->isUnion()
           && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
     }
@@ -361,10 +362,10 @@
     //   If __is_pod (type) is true then the trait is true, else if type is
     //   a cv class or union type (or array thereof) with a trivial default
     //   constructor ([class.ctor]) then the trait is true, else it is false.
-    if (QueriedType->isPODType())
+    if (T->isPODType())
       return true;
     if (const RecordType *RT =
-          C.getBaseElementType(QueriedType)->getAs<RecordType>())
+          C.getBaseElementType(T)->getAs<RecordType>())
       return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
     return false;
   case UTT_HasTrivialCopy:
@@ -373,9 +374,9 @@
     //   the trait is true, else if type is a cv class or union type
     //   with a trivial copy constructor ([class.copy]) then the trait
     //   is true, else it is false.
-    if (QueriedType->isPODType() || QueriedType->isReferenceType())
+    if (T->isPODType() || T->isReferenceType())
       return true;
-    if (const RecordType *RT = QueriedType->getAs<RecordType>())
+    if (const RecordType *RT = T->getAs<RecordType>())
       return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
     return false;
   case UTT_HasTrivialAssign:
@@ -391,11 +392,11 @@
     // errors if the copy assignment operator is actually used, q.v.
     // [class.copy]p12).
 
-    if (C.getBaseElementType(QueriedType).isConstQualified())
+    if (C.getBaseElementType(T).isConstQualified())
       return false;
-    if (QueriedType->isPODType())
+    if (T->isPODType())
       return true;
-    if (const RecordType *RT = QueriedType->getAs<RecordType>())
+    if (const RecordType *RT = T->getAs<RecordType>())
       return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
     return false;
   case UTT_HasTrivialDestructor:
@@ -405,10 +406,10 @@
     //   type (or array thereof) with a trivial destructor
     //   ([class.dtor]) then the trait is true, else it is
     //   false.
-    if (QueriedType->isPODType() || QueriedType->isReferenceType())
+    if (T->isPODType() || T->isReferenceType())
       return true;
     if (const RecordType *RT =
-          C.getBaseElementType(QueriedType)->getAs<RecordType>())
+          C.getBaseElementType(T)->getAs<RecordType>())
       return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
     return false;
   // TODO: Propagate nothrowness for implicitly declared special members.
@@ -420,13 +421,13 @@
     //   or union type with copy assignment operators that are known
     //   not to throw an exception then the trait is true, else it is
     //   false.
-    if (C.getBaseElementType(QueriedType).isConstQualified())
+    if (C.getBaseElementType(T).isConstQualified())
       return false;
-    if (QueriedType->isReferenceType())
+    if (T->isReferenceType())
       return false;
-    if (QueriedType->isPODType())
+    if (T->isPODType())
       return true;
-    if (const RecordType *RT = QueriedType->getAs<RecordType>()) {
+    if (const RecordType *RT = T->getAs<RecordType>()) {
       CXXRecordDecl* RD = cast<CXXRecordDecl>(RT->getDecl());
       if (RD->hasTrivialCopyAssignment())
         return true;
@@ -458,9 +459,9 @@
     //   if type is a cv class or union type with copy constructors that are
     //   known not to throw an exception then the trait is true, else it is
     //   false.
-    if (QueriedType->isPODType() || QueriedType->isReferenceType())
+    if (T->isPODType() || T->isReferenceType())
       return true;
-    if (const RecordType *RT = QueriedType->getAs<RecordType>()) {
+    if (const RecordType *RT = T->getAs<RecordType>()) {
       CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
       if (RD->hasTrivialCopyConstructor())
         return true;
@@ -469,8 +470,7 @@
       bool AllNoThrow = true;
       unsigned FoundTQs;
       DeclarationName ConstructorName
-          = C.DeclarationNames.getCXXConstructorName(
-                                          C.getCanonicalType(QueriedType));
+          = C.DeclarationNames.getCXXConstructorName(C.getCanonicalType(T));
       DeclContext::lookup_const_iterator Con, ConEnd;
       for (llvm::tie(Con, ConEnd) = RD->lookup(ConstructorName);
            Con != ConEnd; ++Con) {
@@ -495,10 +495,9 @@
     //   true, else if type is a cv class or union type (or array
     //   thereof) with a default constructor that is known not to
     //   throw an exception then the trait is true, else it is false.
-    if (QueriedType->isPODType())
+    if (T->isPODType())
       return true;
-    if (const RecordType *RT =
-          C.getBaseElementType(QueriedType)->getAs<RecordType>()) {
+    if (const RecordType *RT = C.getBaseElementType(T)->getAs<RecordType>()) {
       CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
       if (RD->hasTrivialConstructor())
         return true;
@@ -517,7 +516,7 @@
     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
     //   If type is a class type with a virtual destructor ([class.dtor])
     //   then the trait is true, else it is false.
-    if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
+    if (const RecordType *Record = T->getAs<RecordType>()) {
       CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
       if (CXXDestructorDecl *Destructor = RD->getDestructor())
         return Destructor->isVirtual();

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Sep  9 11:14:44 2010
@@ -1832,7 +1832,7 @@
   if (Ty.isInvalid())
     return ExprError();
 
-  return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
+  return Actions.ActOnUnaryTypeTrait(UTT, Loc, Ty.get(), RParen);
 }
 
 /// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Sep  9 11:14:44 2010
@@ -1982,12 +1982,23 @@
 }
 
 ExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
-                                                 SourceLocation KWLoc,
-                                                 SourceLocation LParen,
-                                                 ParsedType Ty,
-                                                 SourceLocation RParen) {
-  QualType T = GetTypeFromParser(Ty);
+                                     SourceLocation KWLoc,
+                                     ParsedType Ty,
+                                     SourceLocation RParen) {
+  TypeSourceInfo *TSInfo;
+  QualType T = GetTypeFromParser(Ty, &TSInfo);
+
+  if (!TSInfo)
+    TSInfo = Context.getTrivialTypeSourceInfo(T);
+  return BuildUnaryTypeTrait(OTT, KWLoc, TSInfo, RParen);
+}
 
+ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait OTT,
+                                     SourceLocation KWLoc,
+                                     TypeSourceInfo *TSInfo,
+                                     SourceLocation RParen) {
+  QualType T = TSInfo->getType();
+  
   // According to http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
   // all traits except __is_class, __is_enum and __is_union require a the type
   // to be complete, an array of unknown bound, or void.
@@ -2004,7 +2015,7 @@
   // There is no point in eagerly computing the value. The traits are designed
   // to be used from type trait templates, so Ty will be a template parameter
   // 99% of the time.
-  return Owned(new (Context) UnaryTypeTraitExpr(KWLoc, OTT, T,
+  return Owned(new (Context) UnaryTypeTraitExpr(KWLoc, OTT, TSInfo,
                                                 RParen, Context.BoolTy));
 }
 

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Sep  9 11:14:44 2010
@@ -1643,12 +1643,10 @@
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
   ExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
-                                         SourceLocation StartLoc,
-                                         SourceLocation LParenLoc,
-                                         QualType T,
-                                         SourceLocation RParenLoc) {
-    return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
-                                         ParsedType::make(T), RParenLoc);
+                                   SourceLocation StartLoc,
+                                   TypeSourceInfo *T,
+                                   SourceLocation RParenLoc) {
+    return getSema().BuildUnaryTypeTrait(Trait, StartLoc, T, RParenLoc);
   }
 
   /// \brief Build a new (previously unresolved) declaration reference
@@ -5614,23 +5612,16 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
-  TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
-
-  QualType T = getDerived().TransformType(E->getQueriedType());
-  if (T.isNull())
+  TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
+  if (!T)
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
-      T == E->getQueriedType())
+      T == E->getQueriedTypeSourceInfo())
     return SemaRef.Owned(E->Retain());
 
-  // FIXME: Bad location information
-  SourceLocation FakeLParenLoc
-    = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
-
   return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
                                             E->getLocStart(),
-                                            /*FIXME:*/FakeLParenLoc,
                                             T,
                                             E->getLocEnd());
 }

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Thu Sep  9 11:14:44 2010
@@ -1249,7 +1249,7 @@
   SourceRange Range = Reader.ReadSourceRange(Record, Idx);
   E->Loc = Range.getBegin();
   E->RParen = Range.getEnd();
-  E->QueriedType = Reader.GetType(Record[Idx++]);
+  E->QueriedType = Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx);
 }
 
 Stmt *ASTReader::ReadStmt(llvm::BitstreamCursor &Cursor) {

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Thu Sep  9 11:14:44 2010
@@ -1279,7 +1279,7 @@
   VisitExpr(E);
   Record.push_back(E->getTrait());
   Writer.AddSourceRange(E->getSourceRange(), Record);
-  Writer.AddTypeRef(E->getQueriedType(), Record);
+  Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
   Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
 }
 

Modified: cfe/trunk/test/Index/load-stmts.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/load-stmts.cpp?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/test/Index/load-stmts.cpp (original)
+++ cfe/trunk/test/Index/load-stmts.cpp Thu Sep  9 11:14:44 2010
@@ -88,6 +88,7 @@
 void test_even_more_dependent_exprs(T t, Y y) {
   typedef T type;
   (void)type(t, y);
+  (void)__has_nothrow_assign(type);
 }
 
 // RUN: c-index-test -test-load-source all %s | FileCheck %s
@@ -195,3 +196,5 @@
 // CHECK: load-stmts.cpp:90:9: TypeRef=type:89:13 Extent=[90:9 - 90:13]
 // CHECK: load-stmts.cpp:90:14: DeclRefExpr=t:88:39 Extent=[90:14 - 90:15]
 // CHECK: load-stmts.cpp:90:17: DeclRefExpr=y:88:44 Extent=[90:17 - 90:18]
+// CHECK: load-stmts.cpp:91:9: UnexposedExpr= Extent=[91:9 - 91:35]
+// CHECK: load-stmts.cpp:91:30: TypeRef=type:89:13 Extent=[91:30 - 91:34]

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=113492&r1=113491&r2=113492&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Thu Sep  9 11:14:44 2010
@@ -366,7 +366,6 @@
   bool VisitCaseStmt(CaseStmt *S);
   bool VisitWhileStmt(WhileStmt *S);
   bool VisitForStmt(ForStmt *S);
-//  bool VisitSwitchCase(SwitchCase *S);
 
   // Expression visitors
   bool VisitDeclRefExpr(DeclRefExpr *E);
@@ -385,12 +384,13 @@
   // FIXME: InitListExpr (for the designators)
   // FIXME: DesignatedInitExpr
   bool VisitCXXTypeidExpr(CXXTypeidExpr *E);
+  bool VisitCXXUuidofExpr(CXXUuidofExpr *E);
   bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { return false; }
   bool VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
   bool VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
   bool VisitCXXNewExpr(CXXNewExpr *E);
   bool VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
-  // FIXME: UnaryTypeTraitExpr has poor source-location information.
+  bool VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
   bool VisitOverloadExpr(OverloadExpr *E);
   bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
   bool VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
@@ -1590,6 +1590,17 @@
   return VisitExpr(E);
 }
 
+bool CursorVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
+  if (E->isTypeOperand()) {
+    if (TypeSourceInfo *TSInfo = E->getTypeOperandSourceInfo())
+      return Visit(TSInfo->getTypeLoc());
+    
+    return false;
+  }
+  
+  return VisitExpr(E);  
+}
+
 bool CursorVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
   if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo())
     return Visit(TSInfo->getTypeLoc());
@@ -1651,6 +1662,10 @@
   return false;
 }
 
+bool CursorVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
+  return Visit(E->getQueriedTypeSourceInfo()->getTypeLoc());
+}
+
 bool CursorVisitor::VisitOverloadExpr(OverloadExpr *E) {
   // Visit the nested-name-specifier.
   if (NestedNameSpecifier *Qualifier = E->getQualifier())





More information about the cfe-commits mailing list