diff options
author | Chad Rosier <mcrosier@apple.com> | 2012-10-25 21:49:22 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@apple.com> | 2012-10-25 21:49:22 +0000 |
commit | 802f93736a9ae76ffcbd90dbaf1c0b185531bb30 (patch) | |
tree | 6c7c3fc22cdcadedeb91ec9fd02942c53d302984 /lib/Sema/SemaStmtAsm.cpp | |
parent | e11dba83d35b861e3a6c0d73ea84f89394cb9bad (diff) |
[ms-inline asm] Add support for field lookup in the SemaCallback. Patch by Eli.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166723 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmtAsm.cpp')
-rw-r--r-- | lib/Sema/SemaStmtAsm.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index 3a5f40c74f..8e6b81472f 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -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; |