diff options
| author | Anders Carlsson <andersca@mac.com> | 2008-11-09 18:54:14 +0000 | 
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2008-11-09 18:54:14 +0000 | 
| commit | 3442f82c2fea5f6ab80afc613550e78579d1a829 (patch) | |
| tree | 7a350e574c2781da3e80e890225cabec32490f5d | |
| parent | b45a43aec4740f3ecfe932ca0b87035bb01b3082 (diff) | |
| download | bcm5719-llvm-3442f82c2fea5f6ab80afc613550e78579d1a829.tar.gz bcm5719-llvm-3442f82c2fea5f6ab80afc613550e78579d1a829.zip  | |
Support named operands in inline asm statements.
llvm-svn: 58940
| -rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 57 | 
1 files changed, 51 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index ece4aeeff89..a9a7a013c6d 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -623,8 +623,16 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {    CaseRangeBlock = SavedCRBlock;  } -static std::string ConvertAsmString(const char *Start, unsigned NumOperands, -                                    bool IsSimple, bool &Failed) { +static std::string ConvertAsmString(const AsmStmt& S, bool &Failed) +{ +  // FIXME: No need to create new std::string here, we could just make sure +  // that we don't read past the end of the string data. +  std::string str(S.getAsmString()->getStrData(), +                  S.getAsmString()->getByteLength()); +  const char *Start = str.c_str(); +   +  unsigned NumOperands = S.getNumOutputs() + S.getNumInputs(); +  bool IsSimple = S.isSimple();    Failed = false;    static unsigned AsmCounter = 0; @@ -697,6 +705,46 @@ static std::string ConvertAsmString(const char *Start, unsigned NumOperands,          Result += "${" + llvm::utostr(n) + ':' + EscapedChar + '}';          Start = End - 1; +      } else if (EscapedChar == '[') { +        std::string SymbolicName; +         +        Start++; +         +        while (*Start && *Start != ']') { +          SymbolicName += *Start; +           +          Start++; +        } +         +        if (!Start) { +          // FIXME: Should be caught by sema. +          assert(0 && "Could not parse symbolic name"); +        } +         +        assert(*Start == ']' && "Error parsing symbolic name"); +         +        int Index = -1; +         +        // Check if this is an output operand. +        for (unsigned i = 0; i < S.getNumOutputs(); i++) { +          if (S.getOutputName(i) == SymbolicName) { +            Index = i; +            break; +          } +        } +         +        if (Index == -1) { +          for (unsigned i = 0; i < S.getNumInputs(); i++) { +            if (S.getInputName(i) == SymbolicName) { +              Index = S.getNumOutputs() + i; +            } +          } +        } +         +        assert(Index != -1 && "Did not find right operand!"); +        +        Result += '$' + llvm::utostr(Index); +        } else {          Failed = true;          return ""; @@ -736,10 +784,7 @@ static std::string SimplifyConstraint(const char* Constraint,  void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {    bool Failed;    std::string AsmString =  -    ConvertAsmString(std::string(S.getAsmString()->getStrData(), -                                 S.getAsmString()->getByteLength()).c_str(), -                     S.getNumOutputs() + S.getNumInputs(), S.isSimple(), -                     Failed); +    ConvertAsmString(S, Failed);    if (Failed) {      ErrorUnsupported(&S, "asm string");  | 

