]> granicus.if.org Git - clang/commitdiff
[ms-inline asm] Add support for field lookup in the SemaCallback. Patch by Eli.
authorChad Rosier <mcrosier@apple.com>
Thu, 25 Oct 2012 21:49:22 +0000 (21:49 +0000)
committerChad Rosier <mcrosier@apple.com>
Thu, 25 Oct 2012 21:49:22 +0000 (21:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166723 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaStmtAsm.cpp

index ecbcbb00fbccfea2ce9da0ae126daf8c4649d583..4183dcf3fce1eb09c6f6db6eee63a451511cfde8 100644 (file)
@@ -2633,6 +2633,8 @@ public:
 
   NamedDecl *LookupInlineAsmIdentifier(StringRef Name, SourceLocation Loc,
                                        unsigned &Size);
+  bool LookupInlineAsmField(StringRef Base, StringRef Member,
+                            unsigned &Offset, SourceLocation AsmLoc);
   StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
                             ArrayRef<Token> AsmToks, SourceLocation EndLoc);
 
index 3a5f40c74fac126faa98ddc6f2ae2105d3e8dc9f..8e6b81472f8710e36237f2cd9aeda47af6b15cef 100644 (file)
@@ -16,6 +16,7 @@
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/AST/RecordLayout.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/TargetInfo.h"
@@ -383,6 +384,11 @@ public:
     return static_cast<void *>(OpDecl);
   }
 
+  bool LookupInlineAsmField(StringRef Base, StringRef Member,
+                            unsigned &Offset) {
+    return SemaRef.LookupInlineAsmField(Base, Member, Offset, AsmLoc);
+  }
+
   static void MSAsmDiagHandlerCallback(const llvm::SMDiagnostic &D,
                                        void *Context) {
     ((MCAsmParserSemaCallbackImpl*)Context)->MSAsmDiagHandler(D);
@@ -446,6 +452,50 @@ NamedDecl *Sema::LookupInlineAsmIdentifier(StringRef Name, SourceLocation Loc,
   return 0;
 }
 
+bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member,
+                                unsigned &Offset, SourceLocation AsmLoc) {
+  Offset = 0;
+  LookupResult BaseResult(*this, &Context.Idents.get(Base), SourceLocation(),
+                          LookupOrdinaryName);
+
+  if (!LookupName(BaseResult, getCurScope()))
+    return true;
+
+  if (!BaseResult.isSingleResult())
+    return true;
+
+  NamedDecl *FoundDecl = BaseResult.getFoundDecl();
+  const RecordType *RT = 0;
+  if (VarDecl *VD = dyn_cast<VarDecl>(FoundDecl)) {
+    RT = VD->getType()->getAs<RecordType>();
+  } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(FoundDecl)) {
+    RT = TD->getUnderlyingType()->getAs<RecordType>();
+  }
+  if (!RT)
+    return true;
+
+  if (RequireCompleteType(AsmLoc, QualType(RT, 0), 0))
+    return true;
+
+  LookupResult FieldResult(*this, &Context.Idents.get(Member), SourceLocation(),
+                           LookupMemberName);
+
+  if (!LookupQualifiedName(FieldResult, RT->getDecl()))
+    return true;
+
+  // FIXME: Handle IndirectFieldDecl?
+  FieldDecl *FD = dyn_cast<FieldDecl>(FieldResult.getFoundDecl());
+  if (!FD)
+    return true;
+
+  const ASTRecordLayout &RL = Context.getASTRecordLayout(RT->getDecl());
+  unsigned i = FD->getFieldIndex();
+  CharUnits Result = Context.toCharUnitsFromBits(RL.getFieldOffset(i));
+  Offset = (unsigned)Result.getQuantity();
+
+  return false;
+}
+
 StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
                                 ArrayRef<Token> AsmToks,SourceLocation EndLoc) {
   SmallVector<IdentifierInfo*, 4> Names;