Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 116978)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -2965,6 +2965,8 @@
 def err_anonymous_record_nonpublic_member : Error<
   "anonymous %select{struct|union}0 cannot contain a "
   "%select{private|protected}1 data member">;
+def ext_ms_anonymous_struct : ExtWarn<
+  "anonymous structs are a Microsoft extension">, InGroup<Microsoft>;
 
 // C++ local classes
 def err_reference_to_local_var_in_enclosing_function : Error<
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 116978)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -779,6 +779,9 @@
                                     AccessSpecifier AS,
                                     RecordDecl *Record);
 
+  Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
+                                       RecordDecl *Record);
+
   bool isAcceptableTagRedeclaration(const TagDecl *Previous,
                                     TagTypeKind NewTag,
                                     SourceLocation NewTagLoc,
@@ -1721,11 +1724,15 @@
                               const CXXScopeSpec *SS = 0);
   VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
                                     llvm::SmallVectorImpl<FieldDecl *> &Path);
+  bool BuildMSAnonymousStructMemberPath(FieldDecl *Field,const RecordDecl *Record,
+                                    llvm::SmallVectorImpl<FieldDecl *> &Path);
   ExprResult
   BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
                                            FieldDecl *Field,
                                            Expr *BaseObjectExpr = 0,
-                                      SourceLocation OpLoc = SourceLocation());
+                                      SourceLocation OpLoc = SourceLocation(),
+                                      bool IsMicrosoftCAnonStruct = false);
+
   ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
                                              LookupResult &R,
                                 const TemplateArgumentListInfo *TemplateArgs);
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 116978)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -1643,11 +1643,15 @@
         << DS.getSourceRange();
     }
 
-    // Microsoft allows unnamed struct/union fields. Don't complain
-    // about them.
-    // FIXME: Should we support Microsoft's extensions in this area?
-    if (Record->getDeclName() && getLangOptions().Microsoft)
-      return Tag;
+    // Check for Microsoft C extension: anonymous struct.
+    if (getLangOptions().Microsoft && !getLangOptions().CPlusPlus &&
+        CurContext->isRecord() && Record->getDeclName() && 
+        !Record->isDefinition() &&
+        DS.getStorageClassSpec() == DeclSpec::SCS_unspecified) {
+      Diag(DS.getSourceRange().getBegin(), diag::ext_ms_anonymous_struct)
+        << DS.getSourceRange();
+      return BuildMicrosoftCAnonymousStruct(S, DS, Record);
+    }
   }
   
   if (getLangOptions().CPlusPlus && 
@@ -1825,7 +1829,7 @@
   llvm_unreachable("unknown storage class specifier");
 }
 
-/// ActOnAnonymousStructOrUnion - Handle the declaration of an
+/// BuildAnonymousStructOrUnion - Handle the declaration of an
 /// anonymous structure or union. Anonymous unions are a C++ feature
 /// (C++ [class.union]) and a GNU C extension; anonymous structures
 /// are a GNU C and GNU C++ extension.
@@ -2013,7 +2017,51 @@
 }
 
 
-/// GetNameForDeclarator - Determine the full declaration name for the
+/// BuildMicrosoftCAnonymousStruct - Handle the declaration of an
+/// Microsoft C anonymous structure.
+/// Ref: http://msdn.microsoft.com/en-us/library/z2cx9y4f.aspx
+/// Example:
+///
+/// struct A { int a; };
+/// struct B { struct A; int b; };
+///
+/// void foo() {
+///   B var;
+///   var.a = 3; 
+/// }
+///
+Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
+                                           RecordDecl *Record) {
+  // Mock up a declarator.
+  Declarator Dc(DS, Declarator::TypeNameContext);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);
+  assert(TInfo && "couldn't build declarator info for anonymous struct");
+
+  // Create a declaration for this anonymous struct.
+  NamedDecl* Anon = FieldDecl::Create(Context,
+                             dyn_cast<RecordDecl>(CurContext),
+                             Record->getLocation(),
+                             /*IdentifierInfo=*/0,
+                             Context.getTypeDeclType(Record),
+                             TInfo,
+                             /*BitWidth=*/0, /*Mutable=*/false);
+  Anon->setImplicit();
+
+  // Add the anonymous struct object to the current context.
+  CurContext->addDecl(Anon);
+  
+  // Inject the members of the anonymous struct into the current
+  // context and into the identifier resolver chain for name lookup
+  // purposes.
+  if (InjectAnonymousStructOrUnionMembers(*this, S, CurContext,
+                                          Record->getDefinition(), AS_none))
+    Anon->setInvalidDecl();
+  Record->setAnonymousStructOrUnion(true);
+
+  return Anon;
+}
+ 
+ /// GetNameForDeclarator - Determine the full declaration name for the
 /// given Declarator.
 DeclarationNameInfo Sema::GetNameForDeclarator(Declarator &D) {
   return GetNameFromUnqualifiedId(D.getName());
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 116978)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -568,15 +568,70 @@
   return BaseObject;
 }
 
+/// \brief Given a field that represents a member of an Microsoft C
+///  anonymous struct, recursively build the path from that field's 
+///  context to the actual member.
+///
+/// \returns true if the field is found.
+bool Sema::BuildMSAnonymousStructMemberPath(FieldDecl *Field,
+                              const RecordDecl *Record,
+                              llvm::SmallVectorImpl<FieldDecl *> &Path) {
+  assert(Field->getDeclContext()->isRecord() &&
+         "Field must be stored inside an struct");
+
+  // Loop every declaration contained in Record.
+  for (DeclContext::decl_iterator Mem = Record->decls_begin(),
+       MemEnd = Record->decls_end(); Mem != MemEnd; ++Mem) {
+    
+    // If we find an anonymous RecordDecl recursively loop inside.
+    if (RecordDecl *RD = dyn_cast<RecordDecl>(*Mem)) {
+      if (RD->isAnonymousStructOrUnion() &&
+          BuildMSAnonymousStructMemberPath(Field, RD->getDefinition(), Path)) {
+          // We found the field, add the implicit field following the anonymous
+          // struct to Path.
+          FieldDecl *ImplicitFD = dyn_cast<FieldDecl>(*++Mem);
+          assert(ImplicitFD && ImplicitFD->isImplicit());
+          Path.push_back(ImplicitFD);
+          return true;
+      }
+    } else if (FieldDecl *FD = dyn_cast<FieldDecl>(*Mem))
+      // We found the anoynous field we were looking for,
+      // add the Field to Path and return true.
+      if (FD == Field) {
+        Path.push_back(FD);
+        return true;
+      }
+  }
+  return false;
+}
+
+
 ExprResult
 Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
                                                FieldDecl *Field,
                                                Expr *BaseObjectExpr,
-                                               SourceLocation OpLoc) {
+                                               SourceLocation OpLoc,
+                                               bool IsMicrosoftCAnonStruct) {
   llvm::SmallVector<FieldDecl *, 4> AnonFields;
-  VarDecl *BaseObject = BuildAnonymousStructUnionMemberPath(Field,
-                                                            AnonFields);
+  VarDecl *BaseObject = 0; 
 
+  // Microsoft C anonymous struct requires a different algorithm
+  // to build the AnonField.
+  if (IsMicrosoftCAnonStruct) {
+    // Remove the pointer type if necessary.
+    QualType ObjectType = BaseObjectExpr->getType();
+    if (const PointerType *ObjectPtr = ObjectType->getAs<PointerType>())
+      ObjectType = ObjectPtr->getPointeeType();
+
+    const RecordType *BaseOjbectRecord =
+      ObjectType.getTypePtr()->getAsStructureType();
+    assert(BaseOjbectRecord && BaseOjbectRecord->getDecl());
+    bool FieldFound = BuildMSAnonymousStructMemberPath(Field,
+                        BaseOjbectRecord->getDecl(), AnonFields);
+    assert(FieldFound && "Microsoft anoynmous field not found");
+  } else
+    BaseObject = BuildAnonymousStructUnionMemberPath(Field, AnonFields);
+  
   // Build the expression that refers to the base object, from
   // which we will build a sequence of member references to each
   // of the anonymous union objects and, eventually, the field we
@@ -2955,6 +3010,15 @@
       return BuildAnonymousStructUnionMemberReference(MemberLoc, FD,
                                                       BaseExpr, OpLoc);
 
+    // At this point, if we are in Microsoft C mode and the RecordDecl context
+    // of the field doesn't match the RecordDecl of the BaseType expression we
+    // can assume this is a Microsoft C anonymous struct field. 
+    if (getLangOptions().Microsoft && !getLangOptions().CPlusPlus &&
+        BaseType->getAs<RecordType>()->getDecl() !=
+        cast<RecordDecl>(FD->getDeclContext()))
+      return BuildAnonymousStructUnionMemberReference(MemberLoc, FD,
+                                                      BaseExpr, OpLoc, true);
+    
     // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
     QualType MemberType = FD->getType();
     if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>())
Index: test/CodeGen/ms-anonymous-struct.c
===================================================================
--- test/CodeGen/ms-anonymous-struct.c	(revision 0)
+++ test/CodeGen/ms-anonymous-struct.c	(revision 0)
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -fms-extensions -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %struct.nested1 = type { i32, i32 }
+struct nested1 {
+    long a1;
+    long b1;
+};
+
+// CHECK: %struct.nested2 = type { i32, %struct.nested1, i32 }
+struct nested2 {
+    long a;
+    struct nested1; 
+    long b;
+};
+
+// CHECK: %struct.test = type { i32, %struct.nested2, i32 }
+struct test {
+    int    x;
+    struct nested2; 
+    int    y;
+};
+
+
+void foo()
+{
+  // CHECK: %var = alloca %struct.test, align 4
+  struct test var;
+
+  // CHECK: getelementptr inbounds %struct.test* %var, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 0
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var.a;
+
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 2
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var.b;
+
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 0
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var.a1;
+
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}var, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 1
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var.b1;
+
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 0
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var.x;
+
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 2
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var.y;
+}
+
+void foo2(struct test* var)
+{
+  // CHECK: alloca %struct.test*, align 4
+  // CHECK-NEXT: store %struct.test* %var, %struct.test** %{{.*}}, align 4
+  // CHECK-NEXT: load %struct.test** %{{.*}}, align 4
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 0
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var->a;
+
+  // CHECK-NEXT: load %struct.test** %{{.*}}, align 4
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 2
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var->b;
+
+  // CHECK-NEXT: load %struct.test** %{{.*}}, align 4
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 0
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var->a1;
+
+  // CHECK-NEXT: load %struct.test** %{{.*}}, align 4
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1
+  // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 1
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var->b1;
+
+  // CHECK-NEXT: load %struct.test** %{{.*}}, align 4
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 0
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var->x;
+
+  // CHECK-NEXT: load %struct.test** %{{.*}}, align 4
+  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 2
+  // CHECK-NEXT: load i32* %{{.*}}, align 4
+  var->y;
+}
+ 
\ No newline at end of file
Index: test/Sema/MicrosoftExtensions.c
===================================================================
--- test/Sema/MicrosoftExtensions.c	(revision 116978)
+++ test/Sema/MicrosoftExtensions.c	(working copy)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions
 
 
 struct A
@@ -31,3 +31,26 @@
 	ENUM2_b = 0x9FFFFFFF, // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
 	ENUM2_c = 0x100000000 // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
 };
+
+
+struct nested1 {
+    long a1;
+};
+
+struct nested2 {
+    long a;
+    struct nested1;  // expected-warning {{anonymous structs are a Microsoft extension}}
+};
+
+struct test {
+    int    x;
+    struct nested2;   // expected-warning {{anonymous structs are a Microsoft extension}}
+};
+
+void foo()
+{
+  struct test var;
+  var.a;
+  var.a1;
+  var.x;
+}
\ No newline at end of file
