[cfe-commits] r69385 - in /cfe/trunk: include/clang/AST/Stmt.h include/clang/Frontend/PCHBitCodes.h include/clang/Frontend/PCHWriter.h lib/AST/Stmt.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp test/PCH/asm.c test/PCH/asm.h

Douglas Gregor dgregor at apple.com
Fri Apr 17 13:57:14 PDT 2009


Author: dgregor
Date: Fri Apr 17 15:57:14 2009
New Revision: 69385

URL: http://llvm.org/viewvc/llvm-project?rev=69385&view=rev
Log:
PCH support for inline assembly statements.

This completes support for all of C (+ extensions). We can (again)
build a PCH file for Carbon.h.


Added:
    cfe/trunk/test/PCH/asm.c
    cfe/trunk/test/PCH/asm.h
Modified:
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/include/clang/Frontend/PCHWriter.h
    cfe/trunk/lib/AST/Stmt.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=69385&r1=69384&r2=69385&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Fri Apr 17 15:57:14 2009
@@ -1004,14 +1004,25 @@
           Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
           StringLiteral **clobbers, SourceLocation rparenloc);
 
+  /// \brief Build an empty inline-assembly statement.
+  explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty) { }
+
+  SourceLocation getAsmLoc() const { return AsmLoc; }
+  void setAsmLoc(SourceLocation L) { AsmLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
   bool isVolatile() const { return IsVolatile; }
+  void setVolatile(bool V) { IsVolatile = V; }
   bool isSimple() const { return IsSimple; }
+  void setSimple(bool V) { IsSimple = false; }
 
   //===--- Asm String Analysis ---===//
 
   const StringLiteral *getAsmString() const { return AsmStr; }
   StringLiteral *getAsmString() { return AsmStr; }
-  
+  void setAsmString(StringLiteral *E) { AsmStr = E; }
+
   /// AsmStringPiece - this is part of a decomposed asm string specification
   /// (for use with the AnalyzeAsmString function below).  An asm string is
   /// considered to be a concatenation of these parts.
@@ -1125,7 +1136,13 @@
   const Expr *getInputExpr(unsigned i) const {
     return const_cast<AsmStmt*>(this)->getInputExpr(i);
   }
-  
+
+  void setOutputsAndInputs(unsigned NumOutputs,
+                           unsigned NumInputs, 
+                           const std::string *Names,
+                           StringLiteral **Constraints,
+                           Stmt **Exprs);
+
   //===--- Other ---===//
   
   /// getNamedOperand - Given a symbolic operand reference like %[foo],
@@ -1138,7 +1155,8 @@
   unsigned getNumClobbers() const { return Clobbers.size(); }
   StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
   const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
-  
+  void setClobbers(StringLiteral **Clobbers, unsigned NumClobbers);
+
   virtual SourceRange getSourceRange() const {
     return SourceRange(AsmLoc, RParenLoc);
   }

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=69385&r1=69384&r2=69385&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Fri Apr 17 15:57:14 2009
@@ -407,7 +407,8 @@
       STMT_RETURN,
       /// \brief A DeclStmt record.
       STMT_DECL,
-      /// FIXME: An AsmStmt record.
+      /// \brief An AsmStmt record.
+      STMT_ASM,
       /// \brief A PredefinedExpr record.
       EXPR_PREDEFINED,
       /// \brief A DeclRefExpr record.

Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=69385&r1=69384&r2=69385&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Fri Apr 17 15:57:14 2009
@@ -129,8 +129,6 @@
   void WriteIdentifierTable();
   void WriteAttributeRecord(const Attr *Attr);
 
-  void AddString(const std::string &Str, RecordData &Record);
-
 public:
   /// \brief Create a new precompiled header writer that outputs to
   /// the given bitstream.
@@ -163,6 +161,9 @@
   /// \brief Emit a declaration name.
   void AddDeclarationName(DeclarationName Name, RecordData &Record);
 
+  /// \brief Add a string to the given record.
+  void AddString(const std::string &Str, RecordData &Record);
+
   /// \brief Add the given statement or expression to the queue of statements to
   /// emit.
   ///

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=69385&r1=69384&r2=69385&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Fri Apr 17 15:57:14 2009
@@ -175,6 +175,22 @@
 }
 
 
+void AsmStmt::setOutputsAndInputs(unsigned NumOutputs,
+                                  unsigned NumInputs, 
+                                  const std::string *Names,
+                                  StringLiteral **Constraints,
+                                  Stmt **Exprs) {
+  this->NumOutputs = NumOutputs;
+  this->NumInputs = NumInputs;
+  this->Names.clear();
+  this->Names.insert(this->Names.end(), Names, Names + NumOutputs + NumInputs);
+  this->Constraints.clear();
+  this->Constraints.insert(this->Constraints.end(), 
+                           Constraints, Constraints + NumOutputs + NumInputs);
+  this->Exprs.clear();
+  this->Exprs.insert(this->Exprs.end(), Exprs, Exprs + NumOutputs + NumInputs);
+}
+
 /// getNamedOperand - Given a symbolic operand reference like %[foo],
 /// translate this into a numeric value needed to reference the same operand.
 /// This returns -1 if the operand name is invalid.
@@ -195,6 +211,10 @@
   return -1;
 }
 
+void AsmStmt::setClobbers(StringLiteral **Clobbers, unsigned NumClobbers) {
+  this->Clobbers.clear();
+  this->Clobbers.insert(this->Clobbers.end(), Clobbers, Clobbers + NumClobbers);
+}
 
 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
 /// it into pieces.  If the asm string is erroneous, emit errors and return

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=69385&r1=69384&r2=69385&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Fri Apr 17 15:57:14 2009
@@ -262,6 +262,7 @@
     unsigned VisitBreakStmt(BreakStmt *S);
     unsigned VisitReturnStmt(ReturnStmt *S);
     unsigned VisitDeclStmt(DeclStmt *S);
+    unsigned VisitAsmStmt(AsmStmt *S);
     unsigned VisitExpr(Expr *E);
     unsigned VisitPredefinedExpr(PredefinedExpr *E);
     unsigned VisitDeclRefExpr(DeclRefExpr *E);
@@ -456,6 +457,42 @@
   return 0;
 }
 
+unsigned PCHStmtReader::VisitAsmStmt(AsmStmt *S) {
+  VisitStmt(S);
+  unsigned NumOutputs = Record[Idx++];
+  unsigned NumInputs = Record[Idx++];
+  unsigned NumClobbers = Record[Idx++];
+  S->setAsmLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setVolatile(Record[Idx++]);
+  S->setSimple(Record[Idx++]);
+  
+  unsigned StackIdx 
+    = StmtStack.size() - (NumOutputs*2 + NumInputs*2 + NumClobbers + 1);
+  S->setAsmString(cast_or_null<StringLiteral>(StmtStack[StackIdx++]));
+
+  // Outputs and inputs
+  llvm::SmallVector<std::string, 16> Names;
+  llvm::SmallVector<StringLiteral*, 16> Constraints;
+  llvm::SmallVector<Stmt*, 16> Exprs;
+  for (unsigned I = 0, N = NumOutputs + NumInputs; I != N; ++I) {
+    Names.push_back(Reader.ReadString(Record, Idx));
+    Constraints.push_back(cast_or_null<StringLiteral>(StmtStack[StackIdx++]));
+    Exprs.push_back(StmtStack[StackIdx++]);
+  }
+  S->setOutputsAndInputs(NumOutputs, NumInputs,
+                         &Names[0], &Constraints[0], &Exprs[0]);
+
+  // Constraints
+  llvm::SmallVector<StringLiteral*, 16> Clobbers;
+  for (unsigned I = 0; I != NumClobbers; ++I)
+    Clobbers.push_back(cast_or_null<StringLiteral>(StmtStack[StackIdx++]));
+  S->setClobbers(&Clobbers[0], NumClobbers);
+
+  assert(StackIdx == StmtStack.size() && "Error deserializing AsmStmt");
+  return NumOutputs*2 + NumInputs*2 + NumClobbers + 1;
+}
+
 unsigned PCHStmtReader::VisitExpr(Expr *E) {
   VisitStmt(E);
   E->setType(Reader.GetType(Record[Idx++]));
@@ -2273,6 +2310,10 @@
       S = new (Context) DeclStmt(Empty);
       break;
 
+    case pch::STMT_ASM:
+      S = new (Context) AsmStmt(Empty);
+      break;
+
     case pch::EXPR_PREDEFINED:
       S = new (Context) PredefinedExpr(Empty);
       break;

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=69385&r1=69384&r2=69385&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Fri Apr 17 15:57:14 2009
@@ -463,6 +463,7 @@
     void VisitBreakStmt(BreakStmt *S);
     void VisitReturnStmt(ReturnStmt *S);
     void VisitDeclStmt(DeclStmt *S);
+    void VisitAsmStmt(AsmStmt *S);
     void VisitExpr(Expr *E);
     void VisitPredefinedExpr(PredefinedExpr *E);
     void VisitDeclRefExpr(DeclRefExpr *E);
@@ -640,6 +641,38 @@
   Code = pch::STMT_DECL;
 }
 
+void PCHStmtWriter::VisitAsmStmt(AsmStmt *S) {
+  VisitStmt(S);
+  Record.push_back(S->getNumOutputs());
+  Record.push_back(S->getNumInputs());
+  Record.push_back(S->getNumClobbers());
+  Writer.AddSourceLocation(S->getAsmLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Record.push_back(S->isVolatile());
+  Record.push_back(S->isSimple());
+  Writer.WriteSubStmt(S->getAsmString());
+
+  // Outputs
+  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
+    Writer.AddString(S->getOutputName(I), Record);
+    Writer.WriteSubStmt(S->getOutputConstraintLiteral(I));
+    Writer.WriteSubStmt(S->getOutputExpr(I));
+  }
+
+  // Inputs
+  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
+    Writer.AddString(S->getInputName(I), Record);
+    Writer.WriteSubStmt(S->getInputConstraintLiteral(I));
+    Writer.WriteSubStmt(S->getInputExpr(I));
+  }
+
+  // Clobbers
+  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
+    Writer.WriteSubStmt(S->getClobber(I));
+
+  Code = pch::STMT_ASM;
+}
+
 void PCHStmtWriter::VisitExpr(Expr *E) {
   VisitStmt(E);
   Writer.AddTypeRef(E->getType(), Record);
@@ -1505,9 +1538,7 @@
            Var->getStorageClass() == VarDecl::Static))
         ExternalDefinitions.push_back(ID);
     } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) {
-      if (Func->isThisDeclarationADefinition() &&
-          Func->getStorageClass() != FunctionDecl::Static &&
-          !Func->isInline())
+      if (Func->isThisDeclarationADefinition())
         ExternalDefinitions.push_back(ID);
     }
   }

Added: cfe/trunk/test/PCH/asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/asm.c?rev=69385&view=auto

==============================================================================
--- cfe/trunk/test/PCH/asm.c (added)
+++ cfe/trunk/test/PCH/asm.c Fri Apr 17 15:57:14 2009
@@ -0,0 +1,11 @@
+// Test this without pch.
+// RUN: clang-cc -include %S/asm.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: clang-cc -emit-pch -o %t %S/asm.h &&
+// RUN: clang-cc -include-pch %t -fsyntax-only -verify %s 
+
+
+void call_f(void) { f(); }
+
+void call_clobbers(void) { clobbers(); }

Added: cfe/trunk/test/PCH/asm.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/asm.h?rev=69385&view=auto

==============================================================================
--- cfe/trunk/test/PCH/asm.h (added)
+++ cfe/trunk/test/PCH/asm.h Fri Apr 17 15:57:14 2009
@@ -0,0 +1,14 @@
+// Header for the PCH test asm.c
+
+void f() {
+  int i;
+
+  asm ("foo\n" : : "a" (i + 2));
+  asm ("foo\n" : [symbolic_name] "=a" (i) : "[symbolic_name]" (i));
+}
+
+void clobbers() {
+  asm ("nop" : : : "ax", "#ax", "%ax");
+  asm ("nop" : : : "eax", "rax", "ah", "al");
+  asm ("nop" : : : "0", "%0", "#0");
+}





More information about the cfe-commits mailing list