]> granicus.if.org Git - clang/commitdiff
AST: Handle qualified array types in typeid() expressions
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 27 Sep 2013 07:04:31 +0000 (07:04 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 27 Sep 2013 07:04:31 +0000 (07:04 +0000)
The intent of getTypeOperand() was to yield an unqualified type.
However QualType::getUnqualifiedType() does not strip away qualifiers on
arrays.

N.B.  This worked fine when typeid() was applied to an expression
because we would inject as implicit cast to the unqualified array type
in the AST.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@191487 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprCXX.h
lib/AST/ExprCXX.cpp
lib/AST/ItaniumMangle.cpp
lib/AST/StmtPrinter.cpp
lib/AST/StmtProfile.cpp
lib/CodeGen/CGExprCXX.cpp
lib/CodeGen/CGExprConstant.cpp
test/CodeGenCXX/typeid.cpp

index a8949fe18b1c88f60f126022e2c05399015eec4c..731d47f723ceb3e67d08a63f21e43cc0c4ad4316 100644 (file)
@@ -566,7 +566,7 @@ public:
 
   /// \brief Retrieves the type operand of this typeid() expression after
   /// various required adjustments (removing reference types, cv-qualifiers).
-  QualType getTypeOperand() const;
+  QualType getTypeOperand(ASTContext &Context) const;
 
   /// \brief Retrieve source information for the type operand.
   TypeSourceInfo *getTypeOperandSourceInfo() const {
@@ -701,7 +701,7 @@ public:
 
   /// \brief Retrieves the type operand of this __uuidof() expression after
   /// various required adjustments (removing reference types, cv-qualifiers).
-  QualType getTypeOperand() const;
+  QualType getTypeOperand(ASTContext &Context) const;
 
   /// \brief Retrieve source information for the type operand.
   TypeSourceInfo *getTypeOperandSourceInfo() const {
index 7478678bf0b13f685d66d2ca3831c6dcd18f7661..c7d2f78104bfc336da15a4bd16f0c9c5a7047df1 100644 (file)
@@ -40,16 +40,18 @@ bool CXXTypeidExpr::isPotentiallyEvaluated() const {
   return false;
 }
 
-QualType CXXTypeidExpr::getTypeOperand() const {
+QualType CXXTypeidExpr::getTypeOperand(ASTContext &Context) const {
   assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
-  return Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType()
-                                                        .getUnqualifiedType();
+  Qualifiers Quals;
+  return Context.getUnqualifiedArrayType(
+      Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType(), Quals);
 }
 
-QualType CXXUuidofExpr::getTypeOperand() const {
+QualType CXXUuidofExpr::getTypeOperand(ASTContext &Context) const {
   assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
-  return Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType()
-                                                        .getUnqualifiedType();
+  Qualifiers Quals;
+  return Context.getUnqualifiedArrayType(
+      Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType(), Quals);
 }
 
 // static
@@ -118,7 +120,7 @@ UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT,
 StringRef CXXUuidofExpr::getUuidAsStringRef(ASTContext &Context) const {
   StringRef Uuid;
   if (isTypeOperand())
-    Uuid = CXXUuidofExpr::GetUuidAttrOfType(getTypeOperand())->getGuid();
+    Uuid = CXXUuidofExpr::GetUuidAttrOfType(getTypeOperand(Context))->getGuid();
   else {
     // Special case: __uuidof(0) means an all-zero GUID.
     Expr *Op = getExprOperand();
index 3b32bdfb2ba43ce7cbb36f237a6f6f68be580045..cb3c920bcf08efcc7eed39102b98c8f4e2a8cc55 100644 (file)
@@ -2879,7 +2879,7 @@ recurse:
     //               ::= te <expression>  # typeid (expression)
     if (TIE->isTypeOperand()) {
       Out << "ti";
-      mangleType(TIE->getTypeOperand());
+      mangleType(TIE->getTypeOperand(Context.getASTContext()));
     } else {
       Out << "te";
       mangleExpression(TIE->getExprOperand());
index df8d2bbf09d5925b222dbc954c800ecdba6e2068..c94ffab97167fe1af935c0fe8cbe2cfe6e0c5495 100644 (file)
@@ -1307,7 +1307,7 @@ void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
 void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
   OS << "typeid(";
   if (Node->isTypeOperand()) {
-    Node->getTypeOperand().print(OS, Policy);
+    Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
   } else {
     PrintExpr(Node->getExprOperand());
   }
@@ -1317,7 +1317,7 @@ void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
 void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
   OS << "__uuidof(";
   if (Node->isTypeOperand()) {
-    Node->getTypeOperand().print(OS, Policy);
+    Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
   } else {
     PrintExpr(Node->getExprOperand());
   }
index cde95ee35143018c6c7ffec3f554dae4e0e28cd0..7612bef58aecab24d2e80a4db2e24119fc7b12e1 100644 (file)
@@ -812,13 +812,13 @@ void StmtProfiler::VisitCXXStdInitializerListExpr(
 void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
   VisitExpr(S);
   if (S->isTypeOperand())
-    VisitType(S->getTypeOperand());
+    VisitType(S->getTypeOperandSourceInfo()->getType());
 }
 
 void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
   VisitExpr(S);
   if (S->isTypeOperand())
-    VisitType(S->getTypeOperand());
+    VisitType(S->getTypeOperandSourceInfo()->getType());
 }
 
 void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) {
index 53140218a011177412fda9fa5f2bdbc90bead6b6..9503fafb81a5b1a8a5c7864f1782e52763b12516 100644 (file)
@@ -1589,8 +1589,8 @@ llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
     ConvertType(E->getType())->getPointerTo();
   
   if (E->isTypeOperand()) {
-    llvm::Constant *TypeInfo = 
-      CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand());
+    llvm::Constant *TypeInfo =
+        CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand(getContext()));
     return Builder.CreateBitCast(TypeInfo, StdTypeInfoPtrTy);
   }
 
index 431ee3c47ffbcd704a6b48e3fae347b16a5d7695..2d3afc96f26667be6a78aabce7e9e45227b269b0 100644 (file)
@@ -966,7 +966,7 @@ public:
       CXXTypeidExpr *Typeid = cast<CXXTypeidExpr>(E);
       QualType T;
       if (Typeid->isTypeOperand())
-        T = Typeid->getTypeOperand();
+        T = Typeid->getTypeOperand(CGM.getContext());
       else
         T = Typeid->getExprOperand()->getType();
       return CGM.GetAddrOfRTTIDescriptor(T);
index f54b60d0cd274fedb9fa0c253e8f3b28c7597001..9d212905e614e6f51fdfae11ed2e3b81f0f12f7a 100644 (file)
@@ -27,6 +27,9 @@ extern A &a;
 // CHECK: @_ZN5Test14a_tiE = global
 const std::type_info &a_ti = typeid(a);
 
+// CHECK: @_ZN5Test18A10_c_tiE = constant %"class.std::type_info"* bitcast ({ i8*, i8* }* @_ZTIA10_c to %"class.std::type_info"*), align 8
+const std::type_info &A10_c_ti = typeid(char const[10]);
+
 // CHECK-LABEL: define i8* @_ZN5Test11fEv
 const char *f() {
   try {