summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Stmt.cpp20
-rw-r--r--clang/lib/Frontend/PCHReader.cpp41
-rw-r--r--clang/lib/Frontend/PCHWriter.cpp37
3 files changed, 95 insertions, 3 deletions
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 8e2cf861f83..67910c8ab62 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -175,6 +175,22 @@ std::string AsmStmt::getInputConstraint(unsigned i) const {
}
+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 @@ int AsmStmt::getNamedOperand(const std::string &SymbolicName) const {
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
diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp
index 8889312090e..da7b4229aa1 100644
--- a/clang/lib/Frontend/PCHReader.cpp
+++ b/clang/lib/Frontend/PCHReader.cpp
@@ -262,6 +262,7 @@ namespace {
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 @@ unsigned PCHStmtReader::VisitDeclStmt(DeclStmt *S) {
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 @@ Stmt *PCHReader::ReadStmt() {
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;
diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp
index e71a60051ab..5775ac4c135 100644
--- a/clang/lib/Frontend/PCHWriter.cpp
+++ b/clang/lib/Frontend/PCHWriter.cpp
@@ -463,6 +463,7 @@ namespace {
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 @@ void PCHStmtWriter::VisitDeclStmt(DeclStmt *S) {
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 @@ void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
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);
}
}
OpenPOWER on IntegriCloud