[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