Stmt *RewriteBreakStmt(BreakStmt *S);
Stmt *RewriteContinueStmt(ContinueStmt *S);
void RewriteCastExpr(CStyleCastExpr *CE);
+ void RewriteLinkageSpec(LinkageSpecDecl *LSD);
// Block rewriting.
void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
if (PD->isThisDeclarationADefinition())
RewriteProtocolDecl(PD);
} else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
+ RewriteLinkageSpec(LSD);
// Recurse into linkage specifications
for (DeclContext::decl_iterator DI = LSD->decls_begin(),
DIEnd = LSD->decls_end();
RewriteForwardClassDecl(DG);
continue;
}
+ else {
+ // Keep track of all interface declarations seen.
+ ObjCInterfacesSeen.push_back(IFace);
+ ++DI;
+ continue;
+ }
}
if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) {
ReplaceText(LocStart, 0, "// ");
}
+void
+RewriteModernObjC::RewriteLinkageSpec(LinkageSpecDecl *LSD) {
+ SourceLocation LocStart = LSD->getExternLoc();
+ if (LocStart.isInvalid())
+ llvm_unreachable("Invalid extern SourceLocation");
+
+ ReplaceText(LocStart, 0, "// ");
+ if (!LSD->hasBraces())
+ return;
+ // FIXME. We don't rewrite well if '{' is not on same line as 'extern'.
+ SourceLocation LocRBrace = LSD->getRBraceLoc();
+ if (LocRBrace.isInvalid())
+ llvm_unreachable("Invalid rbrace SourceLocation");
+ ReplaceText(LocRBrace, 0, "// ");
+}
+
void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
const FunctionType *&FPRetType) {
if (T->isObjCQualifiedIdType())
--- /dev/null
+// RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-attributes -D"__declspec(X)=" %t-rw.cpp
+// rdar://11169733
+
+extern "C" __declspec(dllexport)
+@interface Test @end
+
+@implementation Test @end
+
+extern "C" {
+__declspec(dllexport)
+@interface Test1 @end
+
+@implementation Test1 @end
+
+__declspec(dllexport)
+@interface Test2 @end
+
+@implementation Test2 @end
+};
+