]> granicus.if.org Git - clang/commitdiff
Flip the switch to use OffsetOfExpr unconditionally; feel free to revert if
authorEli Friedman <eli.friedman@gmail.com>
Thu, 5 Aug 2010 10:15:45 +0000 (10:15 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Thu, 5 Aug 2010 10:15:45 +0000 (10:15 +0000)
this breaks something.

I'll wait a few days before cleaning out UnaryOperator::OffsetOf.

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

lib/Sema/SemaExpr.cpp

index 80274e1a6bc9786cbcabbfb2b0ff34b08a920ae2..28b2e99537592bd37377d588aaf833d620a3edb5 100644 (file)
@@ -6990,135 +6990,11 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
   if (ArgTy.isNull())
     return ExprError();
 
-  if (getLangOptions().CPlusPlus) {
-    if (!ArgTInfo)
-      ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc);
-    
-    return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents, 
-                                RPLoc);
-  }
-  
-  // FIXME: The code below is marked for death, once we have proper CodeGen
-  // support for non-constant OffsetOf expressions.
-  
-  bool Dependent = ArgTy->isDependentType();
-  
-  // We must have at least one component that refers to the type, and the first
-  // one is known to be a field designator.  Verify that the ArgTy represents
-  // a struct/union/class.
-  if (!Dependent && !ArgTy->isRecordType())
-    return ExprError(Diag(TypeLoc, diag::err_offsetof_record_type) << ArgTy);
-  
-  // FIXME: Type must be complete per C99 7.17p3 because a declaring a variable
-  // with an incomplete type would be illegal.
-  
-  // Otherwise, create a null pointer as the base, and iteratively process
-  // the offsetof designators.
-  QualType ArgTyPtr = Context.getPointerType(ArgTy);
-  Expr* Res = new (Context) ImplicitValueInitExpr(ArgTyPtr);
-  Res = new (Context) UnaryOperator(Res, UnaryOperator::Deref,
-                                    ArgTy, SourceLocation());
-  
-  // offsetof with non-identifier designators (e.g. "offsetof(x, a.b[c])") are a
-  // GCC extension, diagnose them.
-  // FIXME: This diagnostic isn't actually visible because the location is in
-  // a system header!
-  if (NumComponents != 1)
-    Diag(BuiltinLoc, diag::ext_offsetof_extended_field_designator)
-    << SourceRange(CompPtr[1].LocStart, CompPtr[NumComponents-1].LocEnd);
-  
-  if (!Dependent) {
-    bool DidWarnAboutNonPOD = false;
-    
-    if (RequireCompleteType(TypeLoc, Res->getType(),
-                            diag::err_offsetof_incomplete_type))
-      return ExprError();
-    
-    // FIXME: Dependent case loses a lot of information here. And probably
-    // leaks like a sieve.
-    for (unsigned i = 0; i != NumComponents; ++i) {
-      const OffsetOfComponent &OC = CompPtr[i];
-      if (OC.isBrackets) {
-        // Offset of an array sub-field.  TODO: Should we allow vector elements?
-        const ArrayType *AT = Context.getAsArrayType(Res->getType());
-        if (!AT)
-          return ExprError(Diag(OC.LocEnd, diag::err_offsetof_array_type)
-                           << Res->getType());
-        
-        // FIXME: C++: Verify that operator[] isn't overloaded.
-        
-        // Promote the array so it looks more like a normal array subscript
-        // expression.
-        DefaultFunctionArrayLvalueConversion(Res);
-        
-        // C99 6.5.2.1p1
-        Expr *Idx = static_cast<Expr*>(OC.U.E);
-        // FIXME: Leaks Res
-        if (!Idx->isTypeDependent() && !Idx->getType()->isIntegerType())
-          return ExprError(Diag(Idx->getLocStart(),
-                                diag::err_typecheck_subscript_not_integer)
-                           << Idx->getSourceRange());
-        
-        Res = new (Context) ArraySubscriptExpr(Res, Idx, AT->getElementType(),
-                                               OC.LocEnd);
-        continue;
-      }
-      
-      const RecordType *RC = Res->getType()->getAs<RecordType>();
-      if (!RC)
-        return ExprError(Diag(OC.LocEnd, diag::err_offsetof_record_type)
-                         << Res->getType());
-      
-      // Get the decl corresponding to this.
-      RecordDecl *RD = RC->getDecl();
-      if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
-        if (!CRD->isPOD() && !DidWarnAboutNonPOD &&
-            DiagRuntimeBehavior(BuiltinLoc,
-                                PDiag(diag::warn_offsetof_non_pod_type)
-                                << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
-                                << Res->getType()))
-          DidWarnAboutNonPOD = true;
-      }
-      
-      LookupResult R(*this, OC.U.IdentInfo, OC.LocStart, LookupMemberName);
-      LookupQualifiedName(R, RD);
-      
-      FieldDecl *MemberDecl = R.getAsSingle<FieldDecl>();
-      // FIXME: Leaks Res
-      if (!MemberDecl)
-        return ExprError(Diag(BuiltinLoc, diag::err_no_member)
-                         << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd));
-      
-      // C99 7.17p3:
-      //   (If the specified member is a bit-field, the behavior is undefined.)
-      //
-      // We diagnose this as an error.
-      if (MemberDecl->getBitWidth()) {
-        Diag(OC.LocEnd, diag::err_offsetof_bitfield)
-          << MemberDecl->getDeclName()
-          << SourceRange(BuiltinLoc, RPLoc);
-        Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
-        return ExprError();
-      }
-      
-      // FIXME: C++: Verify that MemberDecl isn't a static field.
-      // FIXME: Verify that MemberDecl isn't a bitfield.
-      if (cast<RecordDecl>(MemberDecl->getDeclContext())->isAnonymousStructOrUnion()) {
-        Res = BuildAnonymousStructUnionMemberReference(
-                                                       OC.LocEnd, MemberDecl, Res, OC.LocEnd).takeAs<Expr>();
-      } else {
-        PerformObjectMemberConversion(Res, /*Qualifier=*/0,
-                                      *R.begin(), MemberDecl);
-        // MemberDecl->getType() doesn't get the right qualifiers, but it
-        // doesn't matter here.
-        Res = new (Context) MemberExpr(Res, false, MemberDecl, OC.LocEnd,
-                                       MemberDecl->getType().getNonReferenceType());
-      }
-    }
-  }
-  
-  return Owned(new (Context) UnaryOperator(Res, UnaryOperator::OffsetOf,
-                                           Context.getSizeType(), BuiltinLoc));
+  if (!ArgTInfo)
+    ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc);
+
+  return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents, 
+                              RPLoc);
 }